package com.yss.reportworld.service.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.*;
import java.util.regex.Pattern;

import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.expr.*;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleSysdateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yss.common.core.constant.RequestDataHelper;
import com.yss.common.core.constant.SecurityConstants;
import com.yss.common.core.domain.ColumnInfo;
import com.yss.common.core.domain.YssResponse;
import com.yss.common.core.enums.YssConfigEnum;
import com.yss.common.core.enums.YssRegularEnum;
import com.yss.common.core.enums.YssStatusEnum;
import com.yss.common.core.enums.YssYseNoEnum;
import com.yss.common.core.exception.BusinessException;
import com.yss.common.core.utils.DateUtils;
import com.yss.common.core.utils.JdbcUtil;
import com.yss.common.core.utils.StringUtils;
import com.yss.common.core.utils.sql.SqlUtil;
import com.yss.common.core.utils.uuid.IdUtils;
import com.yss.common.security.utils.DictUtils;
import com.yss.common.security.utils.SecurityUtils;
import com.yss.reportworld.domain.*;
import com.yss.reportworld.domain.vo.DataBaseVo;
import com.yss.reportworld.domain.vo.SqlScriptVO;
import com.yss.reportworld.enums.ReportWorldDescriptionEnum;
import com.yss.reportworld.enums.ReportWorldEnum;
import com.yss.reportworld.mapper.*;
import com.yss.reportworld.service.*;
import com.yss.reportworld.util.TableInfoUtil;
import com.yss.system.api.RemoteConfigService;
import com.yss.system.api.RemoteUserService;
import com.yss.system.api.domain.SysDictData;
import com.yss.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.datasource.ConnectionHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.CollectionUtils;

import javax.sql.DataSource;

/**
 * SQL脚本管理Service业务层处理
 *
 * @author yss
 * @date 2023-03-27
 */
@Slf4j
@Service
public class SqlScriptServiceImpl extends ServiceImpl<SqlScriptMapper, SqlScript> implements ISqlScriptService {
    @Autowired
    private SqlScriptMapper sqlScriptMapper;
    @Qualifier("dataSource")
    @Autowired
    private DataSource dataSource;
    @Autowired
    private ITableStandardCheckService tableStandardCheckService;
    @Autowired
    private ITableDetailStandardCheckService tableDetailStandardCheckService;
    @Autowired
    private IDemandBugInfoService demandBugInfoService;
    @Autowired
    private IDescriptionService descriptionService;
    @Autowired
    private IWeComService weComService;
    @Autowired
    private RemoteConfigService remoteConfigService;
    @Autowired
    private RemoteUserService remoteUserService;
    @Autowired
    private TableMapper tableMapper;
    @Autowired
    private DatasqlMapper datasqlMapper;
    @Autowired
    private TableDetailMapper tableDetailMapper;
    @Autowired
    private DataReportMapper dataReportMapper;
    @Autowired
    private DataCustomerMapper dataCustomerMapper;
    @Autowired
    private DataModularMapper dataModularMapper;
    @Autowired
    private DataDemandBugMapper dataDemandBugMapper;
    @Autowired
    private TableIndexedMapper tableIndexedMapper;
    @Autowired
    private DatabaseMapper databaseMapper;
    @Autowired
    private IDatabaseCheckService databaseCheckService;
    @Autowired
    private IDatabaseDisposeService databaseDisposeService;
    /**
     * 默认值不能使用的 ORACLE 函数
     */
    private String ORACLE_FUNCTION = "to_char,TO_CHAR";

    /**
     * 查询SQL脚本管理列表
     *
     * @param sqlScript SQL脚本管理
     * @return SQL脚本管理
     */
    @Override
    public List<SqlScript> selectSqlScriptList(SqlScript sqlScript) {
        QueryWrapper<SqlScript> wrapper = new QueryWrapper();
        if (null == sqlScript) {
            return this.list(wrapper);
        }
        if (StringUtils.isNotEmpty(sqlScript.getStrReport())) {
            wrapper.in("b.ID", sqlScript.getStrReport());
        }
        if (StringUtils.isNotEmpty(sqlScript.getStrModular())) {
            wrapper.in("c.ID", sqlScript.getStrModular());
        }
        if (StringUtils.isNotEmpty(sqlScript.getStrCustomer())) {
            wrapper.in("d.ID", sqlScript.getStrCustomer());
        }
        if (StringUtils.isNotEmpty(sqlScript.getDemandBugId())) {
            wrapper.eq("e.ID", sqlScript.getDemandBugId());
        }
        if (StringUtils.isNotEmpty(sqlScript.getDataBaseType())) {
            wrapper.eq("a.DATABASE_TYPE", sqlScript.getDataBaseType());
        }
        if (null != sqlScript.getCoverPrimaryKey()) {
            wrapper.eq("a.COVER_PRIMARY_KEY", sqlScript.getCoverPrimaryKey());
        }
        if (null != sqlScript.getStatus()) {
            wrapper.eq("a.STATUS", sqlScript.getStatus());
        }
        if (StringUtils.isNotEmpty(sqlScript.getVersion())) {
            wrapper.eq("a.VERSION", sqlScript.getVersion());
        }
        if (StringUtils.isNotEmpty(sqlScript.getCreateBy())) {
            wrapper.like("a.CREATE_BY", sqlScript.getCreateBy());
        }
        if (StringUtils.isNotEmpty(sqlScript.getSqlScript())) {
            wrapper.like("a.SQL_SCRIPT", sqlScript.getSqlScript());
        }
        if (StringUtils.isNotEmpty(sqlScript.getParams())) {
            if (null != sqlScript.getParams().get("beginTime") && StringUtils.isNotEmpty(sqlScript.getParams().get("beginTime").toString())) {
                wrapper.ge("a.CREATE_TIME", sqlScript.getParams().get("beginTime"));
            }
            if (null != sqlScript.getParams().get("endTime") && StringUtils.isNotEmpty(sqlScript.getParams().get("endTime").toString())) {
                wrapper.le("a.CREATE_TIME", sqlScript.getParams().get("endTime"));
            }
        }
        // 导出的时候选择了数据，按照选择的数据
        if (StringUtils.isNotEmpty(sqlScript.getIds())) {
            List<String> list = JSONArray.parseArray(sqlScript.getIds(), String.class);
            if (StringUtils.isNotEmpty(list)) {
                wrapper.in("a.ID", list);
            }
        }
        List<SqlScript> list = sqlScriptMapper.querySqlScript(wrapper);
        if (StringUtils.isNotEmpty(list)) {
            for (SqlScript script : list) {
                script.setIsShowUpdate(2);
                // 插入人和登录人相等的时候 才能显示修改按钮
                if (SecurityUtils.getUsername().equals(script.getCreateBy())
                        || SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
                    script.setIsShowUpdate(1);
                }
            }
        }
        this.backUpData();
        return list;
    }

    /**
     * 查询完整的SQL,导出脚本
     *
     * @param sqlScript
     * @return
     */
    public List<SqlScript> selectSqlScriptListSql(SqlScript sqlScript) {
        QueryWrapper<SqlScript> wrapper = new QueryWrapper();
        if (null == sqlScript) {
            return this.list(wrapper);
        }
        if (StringUtils.isNotEmpty(sqlScript.getStrReport())) {
            wrapper.in("b.ID", sqlScript.getStrReport());
        }
        if (StringUtils.isNotEmpty(sqlScript.getStrModular())) {
            wrapper.in("c.ID", sqlScript.getStrModular());
        }
        if (StringUtils.isNotEmpty(sqlScript.getStrCustomer())) {
            wrapper.in("d.ID", sqlScript.getStrCustomer());
        }
        if (StringUtils.isNotEmpty(sqlScript.getDemandBugId())) {
            wrapper.eq("e.ID", sqlScript.getDemandBugId());
        }
        if (StringUtils.isNotEmpty(sqlScript.getDataBaseType())) {
            wrapper.eq("a.DATABASE_TYPE", sqlScript.getDataBaseType());
        }
        if (null != sqlScript.getCoverPrimaryKey()) {
            wrapper.eq("a.COVER_PRIMARY_KEY", sqlScript.getCoverPrimaryKey());
        }
        if (null != sqlScript.getStatus()) {
            wrapper.eq("a.STATUS", sqlScript.getStatus());
        }
        if (StringUtils.isNotEmpty(sqlScript.getVersion())) {
            wrapper.eq("a.VERSION", sqlScript.getVersion());
        }
        if (StringUtils.isNotEmpty(sqlScript.getCreateBy())) {
            wrapper.like("a.CREATE_BY", sqlScript.getCreateBy());
        }
        if (StringUtils.isNotEmpty(sqlScript.getSqlScript())) {
            wrapper.like("a.SQL_SCRIPT", sqlScript.getSqlScript());
        }
        if (StringUtils.isNotEmpty(sqlScript.getParams())) {
            if (null != sqlScript.getParams().get("beginTime") && StringUtils.isNotEmpty(sqlScript.getParams().get("beginTime").toString())) {
                wrapper.ge("a.CREATE_TIME", sqlScript.getParams().get("beginTime"));
            }
            if (null != sqlScript.getParams().get("endTime") && StringUtils.isNotEmpty(sqlScript.getParams().get("endTime").toString())) {
                wrapper.le("a.CREATE_TIME", sqlScript.getParams().get("endTime"));
            }
        }
        // 导出的时候选择了数据，按照选择的数据
        if (StringUtils.isNotEmpty(sqlScript.getIds())) {
            List<String> list = JSONArray.parseArray(sqlScript.getIds(), String.class);
            if (StringUtils.isNotEmpty(list)) {
                wrapper.in("a.ID", list);
            }
        }
        List<SqlScript> list = sqlScriptMapper.querySqlScriptSql(wrapper);
        return list;
    }

    /**
     * 获取版本号
     *
     * @param sqlScript
     * @return
     */
    private List<String> getVersionList(SqlScript sqlScript) {
        List<String> dicvalueListnew = new ArrayList<>();
        // 没有选择 同步后续版本，只放当前选择得版本号
        if (YssYseNoEnum.YES.getCode() != sqlScript.getFollowUpVersion()) {
            dicvalueListnew.add(sqlScript.getVersion());
            return dicvalueListnew;
        }
        // 时候同步修改后续版本,取出选择版本的所有后续版本，循环执行语句
        List<SysDictData> dicvalueList = DictUtils.getDictCache(ReportWorldEnum.REPORT_VERSION.getCode());
        boolean falg = false;
        for (int i = dicvalueList.size() - 1; i >= 0; i--) {  // 获取每个版本的数据信息
            if (StringUtils.isNull(dicvalueList.get(i)) || StringUtils.isEmpty(dicvalueList.get(i).getDictValue())) {
                continue;
            }
            // 匹配上的第一个之后的所有版本号都放进去
            if (!falg && dicvalueList.get(i).getDictValue().equals(sqlScript.getVersion())) {
                falg = true;
            }
            if (falg) {
                dicvalueListnew.add(dicvalueList.get(i).getDictValue());
            }
        }
        return dicvalueListnew;
    }

    /**
     * 检查SQL的规范
     *
     * @param sqlScript
     * @return
     * @throws Exception
     */
    @Transactional
    public String checkSqlScript(SqlScript sqlScript) throws Exception {
        if (null == sqlScript || StringUtils.isBlank(sqlScript.getSqlScript())) {
            throw new BusinessException("获取新增报表世界脚本管理失败，请稍后重试！");
        }
        StringBuffer msgInfo = new StringBuffer();
        ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
        Connection connection = holder.getConnection();
        long startTime = System.currentTimeMillis();
        try {
            if (sqlScript.getSqlScript().toUpperCase().indexOf("CREATE TABLE") > -1
                    && null == sqlScript.getLayered()) {  // 包含建表语句，选择所在分层
                msgInfo.append("***脚本中包含建表语句，请选择表所在分层***").append("\r\n");
                return msgInfo.toString();
            }
            List<String> dicvalueListnew = this.getVersionList(sqlScript);
            if (StringUtils.isEmpty(dicvalueListnew)) {
                msgInfo.append("***没有获取到脚本提交的版本信息，请检查***").append("\r\n");
                return msgInfo.toString();
            }
            // 基础数据表结构调整了，标准库需要执行的调整脚本
            QueryWrapper<Database> databaseQueryWrapper = new QueryWrapper<>();
            databaseQueryWrapper.isNotNull("CODE");
            List<Database> databaseList = databaseMapper.selectList(databaseQueryWrapper);
            Map<String, String> databaseMap = new HashMap<>();
            if (StringUtils.isNotEmpty(databaseList)) {
                for (Database database : databaseList) {
                    databaseMap.put(database.getCode(), database.getCode());
                }
            }
            List<DataBaseVo> baseVoList = new ArrayList<>();
            for (String version : dicvalueListnew) {
                TableInfoUtil.handleTableVersion(version); // 替换表名
                sqlScript.setVersionSuffix(TableInfoUtil.getVersionSuffix(version)); //表的版本号后缀
                //检出SQL语句是不是标准ORACLE的
                List<SQLStatement> stmtList = SqlUtil.validatedSqlScript(sqlScript.getSqlScript(), DbType.ORACLE.getDb());
                if (CollectionUtils.isEmpty(stmtList)) {
                    msgInfo.append("***脚本里面没有解析到SQL语句，请检查！***").append("\r\n");
                    return msgInfo.toString();
                }
                Map<String, String> mapInfo = new LinkedHashMap<>();
                Map<String, String> mapInfoDemandBugInfo = new LinkedHashMap<>();
                if (null == connection) {
                    throw new BusinessException("获取数据库连接出错，请稍后重试！");
                }
                msgInfo.append("**************************版本号【" + version + "】*****************************").append("***\r\n");
                // connection.setAutoCommit(false);
                msgInfo.append("***解析出的独立语句的个数===========" + stmtList.size()).append("***\r\n");
                // 统计语句个数
                int numberDataSql = 0, numberDel = 0, numberCreateTable = 0, numberComment = 0, numberCreateIndex = 0, numberAlterTable = 0,
                        numbDropIndex = 0, numberInsert = 0, numberUpdate = 0;
                // 按照给的语句 从前到后解析
                Map<String, SqlScriptVO> sqlVOMapInsert = new HashMap<>();
                Map<String, SqlScriptVO> sqlVOMapUpdate = new HashMap<>();
                // 检查字段修改和删除跨版本问题
                YssResponse<String> response = remoteConfigService.getConfigByKey(YssConfigEnum.REPORTWORLD_CHECK_VERSION.getCode(), SecurityConstants.INNER);
                for (SQLStatement stmt : stmtList) {
                    if (null == stmt || StringUtils.isEmpty(stmt.toString())) {
                        throw new BusinessException("没有解析出你提交的SQL脚本信息，请检查！");
                    }
                    if (stmt instanceof SQLCreateFunctionStatement || stmt instanceof SQLCreateViewStatement
                            || stmt instanceof SQLCreateSequenceStatement || stmt instanceof SQLCreateProcedureStatement) {
                        // 插入SQL脚本信息
                        this.insertDataSqlInfo(sqlScript, mapInfo, stmt, msgInfo);
                        numberDataSql++;
                        continue;
                    }
                    if (stmt instanceof SQLDeleteStatement) {  //  删除语句   删除修改状态
                        this.sqlDeleteStatement(stmt, sqlScript, mapInfoDemandBugInfo, connection, msgInfo);
                        numberDel++;
                        continue;
                    }
                    if (stmt instanceof SQLCreateTableStatement) {    // 建表语句
                        this.sqlCreateTableStatement(stmt, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo, response.getData());
                        numberCreateTable++;
                        continue;
                    }
                    if (stmt instanceof SQLAlterTableStatement) { // alert语句
                        this.sqlAlterTableStatement(stmt, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo, response.getData(), databaseMap, baseVoList);
                        numberAlterTable++;
                        continue;
                    }
                    if (stmt instanceof SQLCommentStatement) {   //  增加表注释或者字段注释 COMMENT ON TABLE COMMENT ON COLUMN
                        this.sqlCommentStatement(stmt, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo);
                        numberComment++;
                        continue;
                    }
                    if (stmt instanceof SQLCreateIndexStatement) { // 创建索引
                        this.sqlCreateIndexStatement(stmt, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo);
                        numberCreateIndex++;
                        continue;
                    }
                    if (stmt instanceof SQLDropIndexStatement) {   // 删除索引
                        this.sqlDropIndexStatement(stmt, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo);
                        numbDropIndex++;
                        continue;
                    }
                    if (stmt instanceof SQLInsertStatement) {  // 插入语句 插入如果存在业务主键相同就修改
                        this.sqlInsertStatement(stmt, sqlScript, mapInfo, connection, mapInfoDemandBugInfo, msgInfo, sqlVOMapInsert);
                        numberInsert++;
                        continue;
                    }
                    if (stmt instanceof SQLUpdateStatement) { //修改语句
                        this.sqlUpdateStatement(stmt, sqlScript, mapInfo, connection, mapInfoDemandBugInfo, msgInfo, sqlVOMapUpdate);
                        numberUpdate++;
                        continue;
                    }
                    if (stmt instanceof SQLBlockStatement) { // DECLARE ** CLOB;BEGIN **:= BOLB类型插入
                        this.sqlBlockStatement(stmt, sqlScript, mapInfo, connection, mapInfoDemandBugInfo, msgInfo);
                        numberInsert++;
                        continue;
                    }
                    throw new BusinessException("系统不支持你输入的脚本类型，请检查！" + stmt);
                }
                if (numberDataSql + numberDel + numberCreateTable + numberComment + numberCreateIndex + numberAlterTable +
                        numbDropIndex + numberInsert + numberUpdate != stmtList.size()) {
                    throw new BusinessException("解析处理的脚本个数和执行的脚本个数不一致，请检查！");
                }
                for (Map.Entry<String, SqlScriptVO> entry : sqlVOMapInsert.entrySet()) {
                    SqlScriptVO vo = entry.getValue();
                    if (StringUtils.isNull(vo)) {
                        continue;
                    }
                    if (StringUtils.isNotNull(vo.getPStemtUpdate())) {
                        vo.getPStemtUpdate().executeBatch();
                        vo.getPStemtUpdate().close();
                    }
                    if (StringUtils.isNotNull(vo.getPStemtInsert())) {
                        vo.getPStemtInsert().executeBatch();
                        vo.getPStemtInsert().close();
                    }
                    if (StringUtils.isNotNull(vo.getPStemtSelect())) {
                        vo.getPStemtSelect().close();
                    }
                    if (StringUtils.isNotNull(vo.getPStemtSelectPrimaryKey())) {
                        vo.getPStemtSelectPrimaryKey().close();
                    }
                }
                msgInfo.append("***待执行删除语句" + numberDel).append("条，检查通过***\r\n");
                msgInfo.append("***待执行建表语句" + numberCreateTable).append("条，检查通过***\r\n");
                msgInfo.append("***待执行ALERT语句" + numberAlterTable + "条，检查通过***").append("\r\n");
                msgInfo.append("***待执行增加表注释或者增加列注释信息" + numberComment).append("条，检查通过***\r\n");
                msgInfo.append("***待执行创建索引语句" + numberCreateIndex + "条，检查通过***").append("\r\n");
                msgInfo.append("***待执行删除索引句" + numbDropIndex + "条，检查通过***").append("\r\n");
                msgInfo.append("***待执行插入语句" + numberInsert + "条，检查通过***").append("\r\n");
                msgInfo.append("***待执行修改语句" + numberUpdate + "条，检查通过***").append("\r\n");
                msgInfo.append("*******************************************************").append("\r\n");
                // 检查新插入的表和字段信息是否规范
                this.tableStandardCheckInfo(sqlScript, mapInfoDemandBugInfo, msgInfo);
                // 数据对应的报表，模块，客户
                this.insertDataBaseSign(sqlScript, mapInfo);
                this.dataBaseCheckInfo(connection, sqlScript, mapInfoDemandBugInfo, msgInfo, version);
                // 基础数据配置的修改
                this.updateDatabaseInfo(baseVoList, sqlScript, connection, msgInfo);
                long times = System.currentTimeMillis() - startTime;
                msgInfo.append("***总共耗时：" + times / 1000 + "秒***").append("\r\n").append("\r\n").append("\r\n");
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
            long times = System.currentTimeMillis() - startTime;
            msgInfo.append("***总共耗时：" + times / 1000 + "秒***").append("\r\n");
            msgInfo.append("原因：" + ex.getMessage());
            throw new BusinessException("解析SQL出现错误，请检查！\r\n" + msgInfo
                    + "\r\n*******************************************************\r\n");
        } finally {
         /*   if (null != connection) {
                connection.rollback();
                connection.close();
            }*/
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            RequestDataHelper.removeThreadLocal();
        }
        return msgInfo.toString();
    }


    /**
     * 审核脚本
     *
     * @param ids
     * @return
     * @throws Exception
     */
    @Transactional
    public String processSqlScript(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new BusinessException("获取脚本管理失败，请稍后重试！");
        }
        StringBuffer msgInfo = new StringBuffer();
        ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
        Connection connection = holder.getConnection();
        long startTime = System.currentTimeMillis();
        try {
            QueryWrapper<SqlScript> wrapper = new QueryWrapper<>();
            wrapper.in("ID", ids);
            wrapper.in("STATUS", YssStatusEnum.WAITING_REVIEW.getCode());
            wrapper.orderByAsc("CREATE_TIME");
            List<SqlScript> scriptList = this.list(wrapper);
            if (CollectionUtils.isEmpty(scriptList)) {
                throw new BusinessException("没有获取到要审核的脚本，请稍后重试！");
            }
            if (null == connection) {
                throw new BusinessException("获取数据库连接出错，请稍后重试！");
            }
            // 基础数据表结构调整了，标准库需要执行的调整脚本
            QueryWrapper<Database> databaseQueryWrapper = new QueryWrapper<>();
            databaseQueryWrapper.isNotNull("CODE");
            List<Database> databaseList = databaseMapper.selectList(databaseQueryWrapper);
            Map<String, String> databaseMap = new HashMap<>();
            if (StringUtils.isNotEmpty(databaseList)) {
                for (Database database : databaseList) {
                    databaseMap.put(database.getCode(), database.getCode());
                }
            }
            List<DataBaseVo> baseVoList = new ArrayList<>();
            // connection.setAutoCommit(false);
            // 检查字段修改和删除跨版本问题
            YssResponse<String> response = remoteConfigService.getConfigByKey(YssConfigEnum.REPORTWORLD_CHECK_VERSION.getCode(), SecurityConstants.INNER);
            for (SqlScript sqlScript : scriptList) {
                if (null == scriptList || StringUtils.isBlank(sqlScript.getId()) || StringUtils.isBlank(sqlScript.getSqlScript())) {
                    continue;
                }
                List<String> dicvalueListnew = this.getVersionList(sqlScript);
                if (StringUtils.isEmpty(dicvalueListnew)) {
                    msgInfo.append("***没有获取到脚本提交的版本信息，请检查***").append("\r\n");
                    return msgInfo.toString();
                }
                for (String version : dicvalueListnew) {
                    TableInfoUtil.handleTableVersion(version); // 替换表名
                    sqlScript.setVersionSuffix(TableInfoUtil.getVersionSuffix(version)); //表的版本号后缀
                    //检出SQL语句是不是标准ORACLE的
                    List<SQLStatement> stmtList = SqlUtil.validatedSqlScript(sqlScript.getSqlScript(), DbType.ORACLE.getDb());
                    if (CollectionUtils.isEmpty(stmtList)) {
                        msgInfo.append("***脚本里面没有解析到SQL语句，请检查！***").append("\r\n");
                        return msgInfo.toString();
                    }
                    msgInfo.append("**************************版本号【" + version + "】*****************************").append("***\r\n");
                    msgInfo.append("***解析出的独立语句的个数=========" + stmtList.size()).append("***\r\n");
                    // 数据对应的模块，客户，需求BUG信息 ,存放对应的主键和属于哪个基础数据
                    Map<String, String> mapInfo = new LinkedHashMap<>();
                    Map<String, String> mapInfoDemandBugInfo = new LinkedHashMap<>();
                    // 查询当前版本的所有需求BUG
                    QueryWrapper<DemandBugInfo> queryWrapper = new QueryWrapper<>();
                    //queryWrapper.eq("VERSION", sqlScript.getVersion());
                    List<DemandBugInfo> listDemandBugInfo = demandBugInfoService.list(queryWrapper);
                    Map<String, String> mapDemandBugInfo = new HashMap<>();
                    if (!CollectionUtils.isEmpty(listDemandBugInfo)) {
                        for (DemandBugInfo demandBugInfo : listDemandBugInfo) {
                            if (null == demandBugInfo) {
                                continue;
                            }
                            mapDemandBugInfo.put(demandBugInfo.getDemandBugNum(), demandBugInfo.getId());
                        }
                    }
                    // 统计语句个数
                    int numberDataSql = 0, numberDel = 0, numberCreateTable = 0, numberComment = 0, numberCreateIndex = 0, numberAlterTable = 0,
                            numbDropIndex = 0, numberInsert = 0, numberUpdate = 0;
                    sqlScript.setStatus(YssStatusEnum.UNDER_REVIEW.getCode());
                    this.updateById(sqlScript);
                    // 按照给的语句 从前到后解析
                    Map<String, SqlScriptVO> sqlVOMapInsert = new HashMap<>();
                    Map<String, SqlScriptVO> sqlVOMapUpdate = new HashMap<>();
                    for (SQLStatement stmt : stmtList) {
                        if (null == stmt || StringUtils.isEmpty(stmt.toString())) {
                            throw new BusinessException("没有解析出你提交的SQL脚本信息，请检查！");
                        }
                        if (stmt instanceof SQLCreateFunctionStatement || stmt instanceof SQLCreateViewStatement
                                || stmt instanceof SQLCreateSequenceStatement || stmt instanceof SQLCreateProcedureStatement) {
                            // 插入SQL脚本信息
                            this.insertDataSqlInfo(sqlScript, mapInfo, stmt, msgInfo);
                            numberDataSql++;
                            continue;
                        }
                        if (stmt instanceof SQLDeleteStatement) {  //  删除语句   删除修改状态 只能删除正常状态的数据
                            this.sqlDeleteStatement(stmt, sqlScript, mapInfoDemandBugInfo, connection, msgInfo);
                            numberDel++;
                            continue;
                        }
                        if (stmt instanceof SQLCreateTableStatement) {    // 建表语句
                            this.sqlCreateTableStatement(stmt, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo, response.getData());
                            numberCreateTable++;
                            continue;
                        }
                        if (stmt instanceof SQLAlterTableStatement) { // alert语句
                            this.sqlAlterTableStatement(stmt, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo, response.getData(), databaseMap, baseVoList);
                            numberAlterTable++;
                            continue;
                        }
                        if (stmt instanceof SQLCommentStatement) {   //  增加表注释或者字段注释 COMMENT ON TABLE COMMENT ON COLUMN
                            this.sqlCommentStatement(stmt, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo);
                            numberComment++;
                            continue;
                        }
                        if (stmt instanceof SQLCreateIndexStatement) { // 创建索引
                            this.sqlCreateIndexStatement(stmt, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo);
                            numberCreateIndex++;
                            continue;
                        }
                        if (stmt instanceof SQLDropIndexStatement) {   // 删除索引
                            this.sqlDropIndexStatement(stmt, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo);
                            numbDropIndex++;
                            continue;
                        }
                        if (stmt instanceof SQLInsertStatement) {  // 插入语句 插入如果存在业务主键相同就修改
                            this.sqlInsertStatement(stmt, sqlScript, mapInfo, connection, mapInfoDemandBugInfo, msgInfo, sqlVOMapInsert);
                            numberInsert++;
                            continue;
                        }
                        if (stmt instanceof SQLUpdateStatement) { //修改语句 修改正常状态的数据
                            this.sqlUpdateStatement(stmt, sqlScript, mapInfo, connection, mapInfoDemandBugInfo, msgInfo, sqlVOMapUpdate);
                            numberUpdate++;
                            continue;
                        }
                        if (stmt instanceof SQLBlockStatement) { // DECLARE ** CLOB;BEGIN **:= BOLB类型插入
                            this.sqlBlockStatement(stmt, sqlScript, mapInfo, connection, mapInfoDemandBugInfo, msgInfo);
                            numberInsert++;
                            continue;
                        }
                        throw new BusinessException("系统不支持你输入的脚本类型，请检查！" + stmt);
                    }
                    if (numberDataSql + numberDel + numberCreateTable + numberComment + numberCreateIndex + numberAlterTable +
                            numbDropIndex + numberInsert + numberUpdate != stmtList.size()) {
                        throw new BusinessException("解析处理的脚本个数和执行的脚本个数不一致，请检查！");
                    }
                    for (Map.Entry<String, SqlScriptVO> entry : sqlVOMapInsert.entrySet()) {
                        SqlScriptVO vo = entry.getValue();
                        if (StringUtils.isNull(vo)) {
                            continue;
                        }
                        if (StringUtils.isNotNull(vo.getPStemtUpdate())) {
                            vo.getPStemtUpdate().executeBatch();
                            vo.getPStemtUpdate().close();
                        }
                        if (StringUtils.isNotNull(vo.getPStemtInsert())) {
                            vo.getPStemtInsert().executeBatch();
                            vo.getPStemtInsert().close();
                        }
                        if (StringUtils.isNotNull(vo.getPStemtSelect())) {
                            vo.getPStemtSelect().close();
                        }
                        if (StringUtils.isNotNull(vo.getPStemtSelectPrimaryKey())) {
                            vo.getPStemtSelectPrimaryKey().close();
                        }
                    }
                    msgInfo.append("***执行删除语句成功" + numberDel).append("条***\r\n");
                    msgInfo.append("***执行建表语句成功" + numberCreateTable).append("条***\r\n");
                    msgInfo.append("***执行ALERT语句成功" + numberAlterTable + "条***").append("\r\n");
                    msgInfo.append("***执行增加表注释或者增加列注释信息成功" + numberComment).append("条***\r\n");
                    msgInfo.append("***执行创建索引语句成功" + numberCreateIndex + "条***").append("\r\n");
                    msgInfo.append("***执行删除索引句成功" + numbDropIndex + "条***").append("\r\n");
                    msgInfo.append("***执行插入语句成功" + numberInsert + "条***").append("\r\n");
                    msgInfo.append("***执行修改语句成功" + numberUpdate + "条***").append("\r\n");
                    msgInfo.append("*******************************************************").append("\r\n");
                    // 检查新插入的表和字段信息是否规范
                    this.tableStandardCheckInfo(sqlScript, mapInfoDemandBugInfo, msgInfo);
                    // 数据对应的报表，模块，客户
                    this.insertDataBaseSign(sqlScript, mapInfo);
                    // 修改记录
                    this.insertDataBasedataDemandBug(sqlScript, mapInfoDemandBugInfo, mapDemandBugInfo);
                    this.dataBaseCheckInfo(connection, sqlScript, mapInfoDemandBugInfo, msgInfo, version);
                    sqlScript.setStatus(YssStatusEnum.NORMAL.getCode());
                    sqlScript.setApprovalBy(SecurityUtils.getUsername());
                    sqlScript.setApprovalTime(new Date());
                    this.updateById(sqlScript);
                    // 基础数据配置的修改
                    this.updateDatabaseInfo(baseVoList, sqlScript, connection, msgInfo);
                }
            }
            long times = System.currentTimeMillis() - startTime;
            msgInfo.append("***总共耗时：" + times / 1000 + "秒").append("\r\n").append("\r\n").append("\r\n");
            // connection.commit();
        } catch (Exception ex) {
            log.error(ex.getMessage());
            long times = System.currentTimeMillis() - startTime;
            msgInfo.append("***总共耗时：" + times / 1000 + "秒").append("***\r\n");
            //  connection.rollback();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            msgInfo.append("***审核数据失败原因：" + ex.getMessage()).append("***\r\n");
        } finally {
          /*  if (null != connection) {
                connection.close();
            }*/
            RequestDataHelper.removeThreadLocal();
        }
        return msgInfo.toString();
    }


    /**
     * 审核退回功能
     *
     * @param approvalReason
     * @return
     */
    public void rebutSqlScript(List<String> idList, String approvalReason) {
        if (CollectionUtils.isEmpty(idList)) {
            throw new BusinessException("获取脚本管理数据失败，请稍后重试！");
        }
        UpdateWrapper<SqlScript> wrapper = new UpdateWrapper<>();
        wrapper.in("ID", idList);
        SqlScript sqlScript = new SqlScript();
        sqlScript.setApprovalReason(approvalReason);
        sqlScript.setStatus(YssStatusEnum.FAIL_REVIEW.getCode());
        sqlScript.setUpdateTime(new Date());
        sqlScript.setUpdateBy(SecurityUtils.getUsername());
        this.update(sqlScript, wrapper);
        QueryWrapper<SqlScript> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("ID", idList);
        List<SqlScript> list = this.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (SqlScript script : list) {
            if (null == script) {
                continue;
            }
            // 创建的用户 查询对应的用户名称
            YssResponse<LoginUser> response = remoteUserService.getUserInfo(script.getCreateBy(), SecurityConstants.INNER);
            if (StringUtils.isNull(response) || StringUtils.isNull(response.getData())
                    || StringUtils.isNull(response.getData().getSysUser())
                    || StringUtils.isEmpty(response.getData().getSysUser().getNickName())) {
                continue;
            }
            weComService.sendMessage("@" + response.getData().getSysUser().getNickName() + " 你的脚本被退回，原因：" + script.getApprovalReason());
        }
    }


    /**
     * 插入SQL脚本信息  检查时候存在函数，视图等语句
     *
     * @return
     */
    private void insertDataSqlInfo(SqlScript sqlScript, Map<String, String> mapInfo, SQLStatement stmt, StringBuffer msgInfo) throws Exception {
        try {
           /* if (StringUtils.isBlank(sqlScript.getDataBaseType())) {  // 配置要区分数据库类型的数据
                throw new BusinessException("新增函数，视图，储存过程等，需要选择对应的数据库类型，请选择数据库类型！");
            }*/
            String dataSqlName = "", datasql = "", name = "";
            int ftype = 0;
            if ((stmt instanceof SQLCreateFunctionStatement)) { // 函数
                throw new BusinessException("提交的脚本中包含的函数脚本，系统现在不允许提交函数脚本，请联系系统管理员！");
                /*if ("COMMON".equals(sqlScript.getDataBaseType())) {  // 配置要区分数据库类型的数据
                    throw new BusinessException("新增函数，必须区分数据库类型，不能为COMMON，请重新数据库类型！");
                }
                ftype = 1;
                SQLCreateFunctionStatement createFunctionStatement = (SQLCreateFunctionStatement) stmt;
                SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) createFunctionStatement.getName();
                dataSqlName = identifierExpr.getSimpleName();
                if (StringUtils.isBlank(dataSqlName)) {
                    throw new BusinessException("没有获取到创建函数的名称信息，请检查！");
                }
                datasql = createFunctionStatement.toString();
                if (StringUtils.isBlank(datasql)) {
                    throw new BusinessException("没有获取到创建函数的语句信息，请检查！");
                }
                this.nameCheck(dataSqlName);
                msgInfo.append("***脚本中包含函数【" + dataSqlName + "】，请联系脚本审核人员处理！").append("***\r\n");
                name = "函数";*/
            }
            if ((stmt instanceof SQLCreateViewStatement)) { // 视图
                throw new BusinessException("提交的脚本中包含的视图脚本，系统现在不允许提交视图脚本，请联系系统管理员！");
                /*ftype = 2;
                SQLCreateViewStatement createViewStatement = (SQLCreateViewStatement) stmt;
                SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) createViewStatement.getTableSource().getExpr();
                dataSqlName = identifierExpr.getSimpleName(); // 创建的视图名称
                if (StringUtils.isBlank(dataSqlName)) {
                    throw new BusinessException("没有获取到创建视图的名称信息，请检查！");
                }
                datasql = createViewStatement.toString();
                if (StringUtils.isBlank(datasql)) {
                    throw new BusinessException("没有获取到创建视图的语句信息，请检查！");
                }
                this.nameCheck(dataSqlName);
                msgInfo.append("***脚本中包含视图【" + dataSqlName + "】，请联系脚本审核人员处理！").append("***\r\n");
                name = "视图";*/
            }
            if ((stmt instanceof SQLCreateSequenceStatement)) { // 序列
                throw new BusinessException("提交的脚本中包含的序列脚本，系统现在不允许提交序列脚本，请联系系统管理员！");
                /*ftype = 4;
                SQLCreateSequenceStatement createSequenceStatement = (SQLCreateSequenceStatement) stmt;
                SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) createSequenceStatement.getName();
                dataSqlName = identifierExpr.getSimpleName();
                if (StringUtils.isBlank(dataSqlName)) {
                    throw new BusinessException("没有获取到创建序列的名称信息，请检查！");
                }
                datasql = createSequenceStatement.toString();
                if (StringUtils.isBlank(datasql)) {
                    throw new BusinessException("没有获取到创建序列的语句信息，请检查！");
                }
                msgInfo.append("***脚本中包含序列【" + dataSqlName + "】，请联系脚本审核人员处理！").append("***\r\n");*/
            }
            if ((stmt instanceof SQLCreateProcedureStatement)) { // 存储过程
                throw new BusinessException("提交的脚本中包含的存储过程脚本，系统现在不允许提交存储过程脚本，请检查！");
                /*if ("COMMON".equals(sqlScript.getDataBaseType())) {  // 配置要区分数据库类型的数据
                    throw new BusinessException("新增存储过程，必须区分数据库类型，不能为COMMON，请重新数据库类型！");
                }
                ftype = 5;
                SQLCreateProcedureStatement createProcedureStatement = (SQLCreateProcedureStatement) stmt;
                SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) createProcedureStatement.getName();
                dataSqlName = identifierExpr.getSimpleName();
                if (StringUtils.isBlank(dataSqlName)) {
                    throw new BusinessException("没有获取到创建存储过程的名称信息，请检查！");
                }
                datasql = createProcedureStatement.toString();
                if (StringUtils.isBlank(datasql)) {
                    throw new BusinessException("没有获取到创建存储过程的语句信息，请检查！");
                }
                this.nameCheck(dataSqlName);
                msgInfo.append("***脚本中包含存储过程【" + dataSqlName + "】，请联系脚本审核人员处理！").append("***\r\n");
                name = "存储过程";*/
            }
            if (StringUtils.isBlank(dataSqlName) || StringUtils.isBlank(datasql)) {
                return;
            }
            // 查询SQL脚本时候已经存在
            QueryWrapper<Datasql> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("NAME", dataSqlName.toUpperCase());
            queryWrapper.eq("DATABASE_TYPE", sqlScript.getDataBaseType());
            Datasql dataSql = datasqlMapper.selectOne(queryWrapper);
            if (null != dataSql) {
                dataSql.setDatasql(datasql);
                dataSql.setStatus(YssStatusEnum.NORMAL.getCode());
                dataSql.setUpdateBy(SecurityUtils.getUsername());
                dataSql.setUpdateTime(new Date());
                datasqlMapper.updateById(dataSql);
                msgInfo.append("***" + name + "名称【" + dataSqlName.toUpperCase() + "】数据库类型【" + sqlScript.getDataBaseType() + "】的语句已经存在，该数据会被更新，请核对！").append("***\r\n");
                mapInfo.put(dataSql.getId(), ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
                return;
            }
            Datasql dataSqlAdd = new Datasql();
            dataSqlAdd.setId(IdUtils.fastSimpleUUID());
            dataSqlAdd.setCreateBy(SecurityUtils.getUsername());
            dataSqlAdd.setCreateTime(new Date());
            dataSqlAdd.setName(dataSqlName.toUpperCase());
            dataSqlAdd.setChineseName(dataSqlName.toUpperCase());
            dataSqlAdd.setDatasql(datasql);
            dataSqlAdd.setDataBaseType(sqlScript.getDataBaseType());
            dataSqlAdd.setType(ftype);
            dataSqlAdd.setStatus(YssStatusEnum.NORMAL.getCode());
            dataSqlAdd.setVersion(sqlScript.getVersion());
            mapInfo.put(dataSqlAdd.getId(), ReportWorldEnum.REPORT_DATASQL_CODE.getCode());
            //datasqlService.save(dataSqlAdd);
            datasqlMapper.insert(dataSqlAdd);
        } catch (Exception ex) {
            log.error(ex.getMessage());
            throw new BusinessException(/*"解析函数，视图，储存过程SQL脚本语句出错！" + */ex.getMessage());
        }
    }


    /**
     * 删除语句 修改对应数据状态已删除状态
     *
     * @return
     * @throws Exception
     */
    private void sqlDeleteStatement(SQLStatement stmt, SqlScript
            sqlScript, Map<String, String> mapInfoDemandBugInfo, Connection connection, StringBuffer msgInfo) throws Exception {
        PreparedStatement pStemtUpdate = null;
        PreparedStatement pStemtSelect = null;
        ResultSet rs = null;
        try {
            SQLDeleteStatement delete = (SQLDeleteStatement) stmt;
            SQLExprTableSource sqlTableSource = (SQLExprTableSource) delete.getTableSource();
            this.checkTableAlias(sqlTableSource);
            String tableName = sqlTableSource.getName().getSimpleName();  // 删除的表名
            if (StringUtils.isBlank(tableName)) {
                throw new BusinessException("没有获取到删除语句里的表名信息！" + sqlTableSource.getParent());
            }
            String code = ReportWorldEnum.RW_DB_SUFFIX.getCode() + tableName.toUpperCase();
            QueryWrapper<Database> wrapper = new QueryWrapper();
            wrapper.eq("CODE", code);
            Database database = databaseMapper.selectOne(wrapper);
            // 判断是否配置的基础数据
            if (StringUtils.isNull(database)) {
                throw new BusinessException("插入的数据不是基础数据，请检查！" + sqlTableSource.getParent());
            }
            if (null != database.getDataBaseType() && 1 == database.getDataBaseType() && StringUtils.isBlank(sqlScript.getDataBaseType())) {  // 配置要区分数据库类型的数据
                throw new BusinessException("删除的数据需要区分数据库类型，请选择数据库类型！" + sqlTableSource.getParent());
            }
            StringBuffer updateSql = new StringBuffer();
            updateSql.append("UPDATE " + code + sqlScript.getVersionSuffix() + " SET RW_DB_STATUS = ? , RW_DB_EDIT_TIME= ?, RW_DB_EDIT_USER=? ");
            StringBuffer sqlWhere = new StringBuffer();
            SQLExpr opExpr = delete.getWhere();
            if (opExpr instanceof SQLBinaryOpExpr) {
                opExpr = delete.getWhere();
                if (null != opExpr) { // where 条件
                    if (StringUtils.oneOf(opExpr.toString(), "select,SELECT")) {
                        throw new BusinessException("删除的数据不要用子查询，请列除具体值或者按照某一列的值删除！" + sqlTableSource.getParent());
                    }
                    sqlWhere.append(opExpr);
                }
            } else if (opExpr instanceof SQLInListExpr) { // where 条件是单独一个in的时候
                StringJoiner updateWhere = new StringJoiner(",");
                SQLInListExpr listExpr = (SQLInListExpr) opExpr;
                SQLExpr expr = listExpr.getExpr();
                if (expr instanceof SQLPropertyExpr) {
                    throw new BusinessException("删除语句中不用别名，请检查！" + sqlTableSource.getParent());
                }
                SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) listExpr.getExpr();
                sqlWhere.append(identifierExpr.getName()).append(" IN (");// 字段名
                List<SQLExpr> exprList = listExpr.getTargetList();
                for (SQLExpr sqlExpr : exprList) {
                    if (sqlExpr instanceof SQLCharExpr) {
                        SQLCharExpr charExpr = (SQLCharExpr) sqlExpr;
                        updateWhere.add("'" + charExpr.getValue() + "'");
                        continue;
                    }
                    if (sqlExpr instanceof SQLIntegerExpr) { //字符类型
                        SQLIntegerExpr sqlIntegerExpr = (SQLIntegerExpr) sqlExpr;
                        if (null != sqlIntegerExpr) {
                            updateWhere.add(sqlIntegerExpr.getNumber().toString());
                        }
                        continue;
                    }
                    throw new BusinessException("系统没有解析到你修改语句条件的值，请联系管理员！" + sqlExpr.getParent());
                }
                sqlWhere.append(updateWhere);
                sqlWhere.append(")");
            } else if (stmt instanceof OracleDeleteStatement) {
                OracleDeleteStatement delete2 = (OracleDeleteStatement) stmt;
                if (delete2.getWhere() instanceof SQLInSubQueryExpr) {
                    throw new BusinessException("删除的数据不要用子查询，请列除具体值或者按照某一列的值删除！" + stmt);
                }
            } else {
                throw new BusinessException("系统没有解析到你的删除语句，请联系管理员！" + stmt);
            }
            // 按照条件查询 对应数据的主键信息，添加修改记录
            StringBuffer selectSql = new StringBuffer();
            selectSql.append("SELECT RW_DB_ID  FROM " + code + sqlScript.getVersionSuffix());
            if (StringUtils.isNotBlank(sqlWhere.toString())) {
                updateSql.append(" WHERE RW_DB_STATUS = 1 AND ").append(sqlWhere);
                selectSql.append(" WHERE RW_DB_STATUS = 1 AND ").append(sqlWhere);
            } else {
                updateSql.append(" WHERE RW_DB_STATUS = 1  ");
                selectSql.append(" WHERE RW_DB_STATUS = 1  ");
            }
            if (null != database.getDataBaseType() && 1 == database.getDataBaseType()) {  // 配置要区分数据库类型的数据
                updateSql.append(" AND RW_DB_DATABASE_TYPE='").append(sqlScript.getDataBaseType()).append("'");
                selectSql.append(" AND RW_DB_DATABASE_TYPE='").append(sqlScript.getDataBaseType()).append("'");
            }
            // 是否同时存在
            String sqlBuffer = this.getSqlBuffer(sqlScript, code);
            updateSql.append(sqlBuffer);
            selectSql.append(sqlBuffer);
            int count = 0;
            pStemtUpdate = connection.prepareStatement(updateSql.toString());
            pStemtUpdate.setInt(1, YssStatusEnum.DELETED.getCode());
            pStemtUpdate.setTimestamp(2, new java.sql.Timestamp(new Date().getTime()));
            pStemtUpdate.setString(3, sqlScript.getCreateBy());
            pStemtSelect = connection.prepareStatement(selectSql.toString());
            rs = pStemtSelect.executeQuery();
            while (rs.next()) {
                mapInfoDemandBugInfo.put(rs.getString(1), code.toUpperCase());
                count++;
            }
            if (0 == count) {
                msgInfo.append("<font color='red'>***SQL脚本【" + stmt + "】").append("没有删除任何数据，请检查确认！***</font>").append("\r\n");
            }
            if (count > 0) { // 条件不是in ,删除了多条的提示
                msgInfo.append("<font color='red'>***SQL脚本【" + stmt + "】").append("会删除" + count + "条数据，请检查确认！***</font>").append("\r\n");
            }
            pStemtUpdate.execute();
        } catch (Exception ex) {
            log.error(ex.getMessage());
            throw new BusinessException("解析删除语句出错！" + ex.getMessage());
        } finally {
            JdbcUtil.close(rs);
            JdbcUtil.close(pStemtSelect);
            JdbcUtil.close(pStemtUpdate);
        }
    }

    /**
     * 建表语句的解析
     *
     * @param stmt
     * @param sqlScript
     * @return
     * @throws Exception
     */
    private void sqlCreateTableStatement(SQLStatement stmt, SqlScript sqlScript, Map<String, String> mapInfo,
                                         Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo, String checkVersion) throws Exception {
        List<Table> tableList = new ArrayList<>();
        try {
            // 包含有建表语句，就需要选择表所在分层
            if (null == sqlScript.getLayered()) {
                throw new BusinessException("脚本中包含建表语句，请选择表所在分层！");
            }
            SQLCreateTableStatement statement = (SQLCreateTableStatement) stmt;
            // 获取表名
            SQLExprTableSource tableSource = statement.getTableSource();
            this.checkTableAlias(tableSource);
            String tableName = tableSource.getName().getSimpleName();
            if (StringUtils.isBlank(tableName)) {
                throw new BusinessException("建表语句没有获到正确的表名信息！");
            }
            this.nameCheck(tableName);
            QueryWrapper<Table> wrapper = new QueryWrapper<>();
            wrapper.eq("NAME", tableName.toUpperCase());
            Table tableOld = tableMapper.selectOne(wrapper);
            String tableId = "";
            boolean falg = false; // 表是否存在
            if (null != tableOld) { // 表已经存在修改表信息
                // throw new BusinessException("系统已经存在表信息，请检查！" + tableName);
                tableOld.setName(tableName);
                tableOld.setStatus(YssStatusEnum.NORMAL.getCode());
                tableOld.setVersion(sqlScript.getVersion());
                if (null != sqlScript.getLayered()) {
                    tableOld.setLayered(sqlScript.getLayered());
                }
                tableOld.setUpdateBy(sqlScript.getCreateBy());
                tableOld.setUpdateTime(new Date());
                tableList.add(tableOld);
                tableMapper.updateById(tableOld);
                mapInfo.put(tableOld.getId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                mapInfoDemandBugInfo.put(tableOld.getId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                tableId = tableOld.getId();
                falg = true;
                msgInfo.append("***表【" + tableName).append("】已经存在，表信息将被覆盖，请检查确认！***\r\n");
            } else {
                //表不存在创建表信息
                tableId = IdUtils.fastSimpleUUID();
                Table table = new Table();
                table.setId(tableId);
                table.setName(tableName);
                table.setStatus(YssStatusEnum.NORMAL.getCode());
                table.setFileName(sqlScript.getId()); // 表里文件来源脚本的编号
                table.setVersion(sqlScript.getVersion());
                table.setLayered(sqlScript.getLayered());
                table.setCreateBy(sqlScript.getCreateBy());
                table.setCreateTime(new Date());
                tableList.add(table);
                tableMapper.insert(table);
                mapInfo.put(tableId, ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                mapInfoDemandBugInfo.put(tableId, ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            }
            List<SQLTableElement> list = statement.getTableElementList();
            int sequence = 1;
            // 主键字段集合
            List<String> pkList = new ArrayList<>();
            for (SQLTableElement element : list) {
                if (null == element) {
                    throw new BusinessException("获取建表语句信息失败，请稍后重试！" + tableName);
                }
                // 创建主键语句   CONSTRAINT  PRIMARY KEY ()
                if (element instanceof OraclePrimaryKey) {
                    OraclePrimaryKey primaryKey = (OraclePrimaryKey) element;
                    List<SQLSelectOrderByItem> columns = primaryKey.getColumns(); // 主键字段
                    if (!CollectionUtils.isEmpty(columns)) {
                        for (SQLSelectOrderByItem item : columns) {
                            if (null == item) {
                                continue;
                            }
                            SQLIdentifierExpr expr = (SQLIdentifierExpr) item.getExpr();
                            pkList.add(expr.getName());
                        }
                    }
                }
            }
            for (SQLTableElement element : list) {
                if (null == element) {
                    throw new BusinessException("获取建表语句信息失败，请稍后重试！" + tableName);
                }
                if (element instanceof OraclePrimaryKey) { //主键已经取出来了
                    continue;
                }
                if (element instanceof SQLColumnDefinition) {
                    SQLColumnDefinition definition = (SQLColumnDefinition) element;
                    sequence++;
                    TableDetail detail = this.getTableDetail(definition, tableId, sequence, sqlScript);
                    if (!CollectionUtils.isEmpty(pkList) && pkList.contains(detail.getColumnName())) {
                        detail.setPrimaryKey(1);
                    }
                    if (falg) { //表已经存在查询字段是否存在
                        QueryWrapper<TableDetail> detailQueryWrapper = new QueryWrapper<>();
                        detailQueryWrapper.eq("TABLE_ID", tableId);
                        detailQueryWrapper.eq("COLUMN_NAME", detail.getColumnName().toUpperCase());
                        TableDetail detailOld = tableDetailMapper.selectOne(detailQueryWrapper);
                        if (null != detailOld) {
                            if (!this.checkVersion(detailOld.getVersion(), checkVersion)) {
                                this.checkTableLength(detailOld, detail, tableName);
                            }
                            BeanUtils.copyProperties(detail, detailOld, new String[]{"id", "sequence"});
                            detailOld.setUpdateBy(sqlScript.getCreateBy());
                            detailOld.setUpdateTime(new Date());
                            detailOld.setStatus(YssStatusEnum.NORMAL.getCode());
                            detailOld.setVersion(sqlScript.getVersion());
                            tableDetailMapper.updateById(detailOld);
                            mapInfo.put(detailOld.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                            mapInfoDemandBugInfo.put(detailOld.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                            msgInfo.append("<font color='red'>***表【" + tableName).append("】字段【" + detailOld.getColumnName() + "】已经存在，字段信息将被覆盖，请检查确认！***</font>\r\n");
                        } else {
                            detail.setCreateBy(sqlScript.getCreateBy());
                            detail.setCreateTime(new Date());
                            tableDetailMapper.insert(detail);
                            mapInfo.put(detail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                            mapInfoDemandBugInfo.put(detail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                        }
                    } else {
                        detail.setCreateBy(sqlScript.getCreateBy());
                        detail.setCreateTime(new Date());
                        tableDetailMapper.insert(detail);
                        mapInfo.put(detail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                        mapInfoDemandBugInfo.put(detail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                    }
                } else {
                    throw new BusinessException("建表语句获取字段信息失败！" + stmt.getParent());
                }
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
            throw new BusinessException("解析建表语句出错！" + ex.getMessage());
        }
    }

    /**
     * 接卸增加字段信息的脚本
     *
     * @param element
     * @param tableId
     * @param sequence
     * @param sqlScript
     * @return
     * @throws Exception
     */
    private TableDetail getTableDetail(SQLColumnDefinition element, String tableId, int sequence, SqlScript sqlScript) throws Exception {
        return this.getTableDetail(element, tableId, sequence, sqlScript, true);
    }

    /**
     * 接卸增加字段信息的脚本
     *
     * @param element
     * @param tableId
     * @param sequence
     * @param sqlScript
     * @param isAdd     是否新增
     * @return
     * @throws Exception
     */
    private TableDetail getTableDetail(SQLColumnDefinition element, String tableId, int sequence, SqlScript sqlScript, boolean isAdd) throws Exception {
        SQLColumnDefinition definition = element;
        ColumnInfo columnInfo = new ColumnInfo();
        // 字段名称
        SQLIdentifierExpr expr = (SQLIdentifierExpr) definition.getName();
        if (StringUtils.isBlank(expr.getName())) {
            throw new BusinessException("获取字段名称出错，请稍后重试！");
        }
        this.nameCheck(expr.getName());
        columnInfo.setName(expr.getName().toUpperCase());
        // 字段类型和长度相关
        SQLDataTypeImpl sqlDataType = (SQLDataTypeImpl) definition.getDataType();
        if (isAdd && null == sqlDataType) {
            throw new BusinessException("添加的字段没有获取到字段类型和长度信息！");
        }
        if (null != sqlDataType) {
            String name = sqlDataType.getName();
            if (StringUtils.isBlank(name)) {
                throw new BusinessException("没有获取到字段类型！【" + element.toString() + "】");
            }
            columnInfo.setDataTypeName(name.toUpperCase());
            List<SQLExpr> exprList = sqlDataType.getArguments();
            for (int i = 0; i < exprList.size(); i++) {
                if (null == exprList.get(i)) {
                    continue;
                }
                if (i == 0) { // 整数位数
                    SQLIntegerExpr integerExpr = (SQLIntegerExpr) exprList.get(i);
                    columnInfo.setPrecision(integerExpr.getNumber().intValue());
                    continue;
                }
                if (i == 1) { // 小数位数
                    SQLIntegerExpr integerExpr = (SQLIntegerExpr) exprList.get(i);
                    columnInfo.setScale(integerExpr.getNumber().intValue());
                    break;
                }
            }
        }
        // 默认值
        SQLExpr sqlExpr = definition.getDefaultExpr();
        if (null != sqlExpr) {
            if (sqlExpr instanceof SQLCharExpr) { //字符类型
                if (!StringUtils.oneCase(columnInfo.getDataTypeName(), "VARCHAR2,VARCHAR,CLOB,BLOB,NCLOB,NVARCHAR2,CHAR")) {
                    throw new BusinessException("字段类型不是字符类型，默认值不能设置为字符类型！" + sqlExpr.getParent());
                }
                SQLCharExpr invokeExpr = (SQLCharExpr) definition.getDefaultExpr();
                if (null != invokeExpr) {
                    // 字符类型的默认值要有单引号
                    columnInfo.setDefaultValue("'" + invokeExpr.getText() + "'");
                }
            } else if (sqlExpr instanceof SQLIntegerExpr) { //数字类型
                if (!StringUtils.oneCase(columnInfo.getDataTypeName(), "NUMBER,INTEGER,FLOAT")) {
                    throw new BusinessException("字段类型不是数字类型，默认值不能设置为数字类型！" + sqlExpr.getParent());
                }
                SQLIntegerExpr invokeExpr = (SQLIntegerExpr) definition.getDefaultExpr();
                if (null != invokeExpr) {
                    columnInfo.setDefaultValue(invokeExpr.getNumber().toString());
                }
            } else if (sqlExpr instanceof SQLMethodInvokeExpr) { // 方法类型 如 sys_guid()
                SQLMethodInvokeExpr invokeExpr = (SQLMethodInvokeExpr) definition.getDefaultExpr();
                if (null != invokeExpr && !StringUtils.oneOf(invokeExpr.toString().toUpperCase(), "SYS_GUID,TO_CHAR,TO_DATE,TO_TIMESTAMP")) {
                    throw new BusinessException("你的默认值设置系统不支持，请联系系统管理员！" + sqlExpr.getParent());
                }
                if (StringUtils.oneOf(invokeExpr.toString().toUpperCase(), "SYS_GUID,TO_CHAR")
                        && !StringUtils.oneCase(columnInfo.getDataTypeName(), "VARCHAR2,VARCHAR,CLOB,BLOB,NCLOB,NVARCHAR2,CHAR")) {
                    throw new BusinessException("字段类型不是字符类型，默认值不能设置为字符类型！" + sqlExpr.getParent());
                }
                if (StringUtils.oneOf(invokeExpr.toString().toUpperCase(), "TO_DATE,TO_TIMESTAMP")
                        && !StringUtils.oneCase(columnInfo.getDataTypeName(), "DATE,TIMESTAMP")) {
                    throw new BusinessException("字段类型不是日期类型，默认值不能设置为日期类型！" + sqlExpr.getParent());
                }
                if (null != invokeExpr) {
                    columnInfo.setDefaultValue(invokeExpr.toString());
                }
            } else if (sqlExpr instanceof OracleSysdateExpr) { // ORACLE 的 SYSDATE默认值
                if (!StringUtils.oneCase(columnInfo.getDataTypeName(), "DATE,TIMESTAMP")) {
                    throw new BusinessException("字段类型不是日期类型，默认值不能设置日期类型！" + sqlExpr.getParent());
                }
                OracleSysdateExpr invokeExpr = (OracleSysdateExpr) definition.getDefaultExpr();
                if (null != invokeExpr) {
                    columnInfo.setDefaultValue(invokeExpr.toString());
                }
            } else if (sqlExpr instanceof SQLNumberExpr) { //Number类型
                if (!StringUtils.oneCase(columnInfo.getDataTypeName(), "NUMBER,FLOAT")) {
                    throw new BusinessException("字段类型不是数字类型，默认值不能设置为数字类型！" + sqlExpr.getParent());
                }
                SQLNumberExpr sqlNumberExpr = (SQLNumberExpr) sqlExpr;
                if (null != sqlNumberExpr) {
                    columnInfo.setDefaultValue(sqlNumberExpr.getNumber().toString());
                }
            } /*else if (sqlExpr instanceof SQLTimestampExpr) {
                if (!StringUtils.oneCase(columnInfo.getDataTypeName(), "DATE,TIMESTAMP")) {
                    throw new BusinessException("字段类型不是日期类型，默认值不能设置日期类型！" + sqlExpr.getParent());
                }
                SQLTimestampExpr invokeExpr = (SQLTimestampExpr) sqlExpr;
                if (null != invokeExpr) {
                    columnInfo.setDefaultValue(invokeExpr.getLiteral());
                }
            }*/ else if (sqlExpr instanceof SQLIdentifierExpr) { // systimestamp
                SQLIdentifierExpr invokeExpr = (SQLIdentifierExpr) sqlExpr;
                if (null != invokeExpr && !StringUtils.oneCase(invokeExpr.getName().toUpperCase(), "SYSTIMESTAMP,TIMESTAMP")) {
                    throw new BusinessException("你的默认值设置系统不支持，请联系系统管理员！" + sqlExpr.getParent());
                }
                if (!StringUtils.oneCase(columnInfo.getDataTypeName(), "DATE,TIMESTAMP")) {
                    throw new BusinessException("字段类型不是日期类型，默认值不能设置日期类型！" + sqlExpr.getParent());
                }
                if (null != invokeExpr && StringUtils.oneCase(invokeExpr.getName().toUpperCase(), "SYSTIMESTAMP,TIMESTAMP")) {
                    columnInfo.setDefaultValue(invokeExpr.getName());
                }
            } else {
                throw new BusinessException("系统没有解析到你配置的默认值类型，请联系管理员！" + sqlExpr.getParent());
            }
        }
        // 是否主键，为空的判断
        List<SQLColumnConstraint> constraintList = definition.getConstraints();
        columnInfo.setIsNull(String.valueOf(YssYseNoEnum.YES.getCode()));
        columnInfo.setPrimaryKey(YssYseNoEnum.NO.getCode());
        if (!CollectionUtils.isEmpty(constraintList)) {
            for (SQLColumnConstraint constraint : constraintList) {
                if (null == constraint) {
                    continue;
                }
                if (constraint instanceof SQLNotNullConstraint) {
                    columnInfo.setIsNull(String.valueOf(YssYseNoEnum.NO.getCode()));
                }
                if (constraint instanceof SQLColumnPrimaryKey) {
                    columnInfo.setPrimaryKey(YssYseNoEnum.YES.getCode());
                }
            }
        }
        // 转换成表明细信息的集合
        TableDetail detail = TableInfoUtil.getReportTableDetail(columnInfo, tableId);
        detail.setStatus(YssStatusEnum.NORMAL.getCode());
        detail.setOrderNum(sequence);
        if (isAdd) {
            detail.setFileName(sqlScript.getId()); // 表里文件来源脚本的编号
        }
        detail.setVersion(sqlScript.getVersion());
        return detail;
    }


    /**
     * Alter
     *
     * @param stmt
     * @param sqlScript
     * @param mapInfo
     * @return
     */
    private void sqlAlterTableStatement(SQLStatement stmt, SqlScript
            sqlScript, Map<String, String> mapInfo, Map<String, String> mapInfoDemandBugInfo,
                                        StringBuffer msgInfo, String checkVersion, Map<String, String> databaseMap, List<DataBaseVo> baseVoList) throws Exception {
        SQLAlterTableStatement statement = (SQLAlterTableStatement) stmt;
        List<SQLAlterTableItem> items = statement.getItems();
        for (SQLAlterTableItem item : items) {
            if (item instanceof SQLAlterTableDropIndex) {
                throw new BusinessException("系统还没有处理该类型的语句，请联系管理员！");
            } else if (item instanceof SQLAlterTableAddIndex) {
                throw new BusinessException("系统还没有处理该类型的语句，请联系管理员！");
            } else if (item instanceof SQLAlterTableDropColumnItem) {  // 删除的列名
                this.sqlAlterTableDropColumnItem(item, sqlScript, mapInfo, mapInfoDemandBugInfo, checkVersion, databaseMap, baseVoList);
                continue;
            } else if (item instanceof SQLAlterTableAddColumn) { //添加表字段
                this.sqlAlterTableAddColumn(item, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo, checkVersion, databaseMap, baseVoList);
                continue;
            } else if (item instanceof OracleAlterTableModify) { // 修改列信息
                this.oracleAlterTableModify(item, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo, checkVersion, databaseMap, baseVoList);
                continue;
            } else if (item instanceof SQLAlterTableDropConstraint) {  // 删除主键
                this.sqlAlterTableDropConstraint(item, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo, databaseMap, baseVoList);
                continue;
            } else if (item instanceof SQLAlterTableAddConstraint) {  // 添加主键
                this.sqlAlterTableAddConstraint(item, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo, databaseMap, baseVoList);
                continue;
            } else if (item instanceof SQLAlterTableRenameColumn) { // 修改字段名称
                this.sqlAlterTableRenameColumn(item, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo, checkVersion, databaseMap, baseVoList);
                continue;
            } else if (item instanceof SQLAlterTableRename) { // 修改表名
                this.sqlAlterTableRename(item, sqlScript, mapInfo, mapInfoDemandBugInfo, msgInfo, checkVersion, databaseMap, baseVoList);
                continue;
            }
        }
    }

    /**
     * 获取表信息
     *
     * @param tableName
     * @return
     * @throws Exception
     */
    private Table getTableInfo(String tableName) throws Exception {
        if (StringUtils.isBlank(tableName)) {
            throw new BusinessException(tableName + "没有获取到表名称信息");
        }
        QueryWrapper<Table> wrapper = new QueryWrapper<>();
        wrapper.eq("NAME", tableName.toUpperCase());
        Table table = tableMapper.selectOne(wrapper);
        if (null == table) {
            log.error("系统不存在需要创建索引的表信息！");
            throw new BusinessException(tableName + "系统不存在表信息，请检查！");
        }
        return table;
    }

    /**
     * 添加字段
     *
     * @param item
     * @param sqlScript
     * @param mapInfo
     * @return
     * @throws Exception
     */
    private void sqlAlterTableAddColumn(SQLAlterTableItem item, SqlScript sqlScript, Map<String, String> mapInfo,
                                        Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo, String checkVersion,
                                        Map<String, String> databaseMap, List<DataBaseVo> baseVoList) throws
            Exception {
        SQLAlterTableAddColumn addColumn = (SQLAlterTableAddColumn) item;
        SQLAlterTableStatement statement = (SQLAlterTableStatement) addColumn.getParent();
        SQLExprTableSource exprTableSource = statement.getTableSource();
        this.checkTableAlias(exprTableSource);
        String tableName = statement.getTableName();// 表名
        Table table = this.getTableInfo(tableName);
        List<SQLColumnDefinition> list = addColumn.getColumns();
        if (CollectionUtils.isEmpty(list)) {
            throw new BusinessException("没有获取到要添加的字段信息，请检查！" + addColumn.getParent());
        }
        // 查询字段现在最大顺序
        QueryWrapper<TableDetail> wrapper = new QueryWrapper<>();
        wrapper.eq("TABLE_ID", table.getId());
        wrapper.select("MAX(ORDER_NUM) AS ORDER_NUM");
        TableDetail detailOld = tableDetailMapper.selectOne(wrapper);
        int sequence = 1;
        if (null != detailOld && null != detailOld.getOrderNum()) {
            sequence = detailOld.getOrderNum() + 1;
        }
        for (SQLColumnDefinition definition : list) {
            if (null == definition) {
                continue;
            }
            // 字段名称
            SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) definition.getName();
            if (StringUtils.isBlank(identifierExpr.getName())) {
                throw new BusinessException("获取字段名称出错，请稍后重试！");
            }
            // 添加表字段查询是否已经存在
            QueryWrapper<TableDetail> detailQueryWrapper = new QueryWrapper<>();
            detailQueryWrapper.eq("TABLE_ID", table.getId());
            detailQueryWrapper.eq("COLUMN_NAME", identifierExpr.getName().toUpperCase());
            TableDetail detailOldOne = tableDetailMapper.selectOne(detailQueryWrapper);
            if (null != detailOldOne) { // 修改成新的
                TableDetail detail = this.getTableDetail(definition, table.getId(), sequence, sqlScript);
                if (!this.checkVersion(detailOldOne.getVersion(), checkVersion)) {
                    this.checkTableLength(detailOldOne, detail, tableName);
                }
                SQLCharExpr expr = (SQLCharExpr) definition.getComment();
                if (null != expr) {
                    String columnChineseName = expr.getText();
                    if (StringUtils.isBlank(columnChineseName)) {
                        throw new BusinessException("增加字段的表没有注释信息，请检查！" + addColumn.getParent());
                    }
                    detailOldOne.setColumnChineseName(columnChineseName);
                }
                BeanUtils.copyProperties(detail, detailOldOne, new String[]{"id", "sequence"});
                detailOldOne.setUpdateBy(sqlScript.getCreateBy());
                detailOldOne.setUpdateTime(new Date());
                detailOldOne.setStatus(YssStatusEnum.NORMAL.getCode());
                detailOldOne.setVersion(sqlScript.getVersion());
                tableDetailMapper.updateById(detailOldOne);
                mapInfo.put(detailOldOne.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                mapInfoDemandBugInfo.put(detailOldOne.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                // 添加表字段，把表也放到对应得所属报表，模块，客户
                // mapInfo.put(table.getId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                mapInfoDemandBugInfo.put(table.getId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                msgInfo.append("<font color='red'>***表【" + tableName + "】").append("字段【" + identifierExpr.getName().toUpperCase() + "】")
                        .append("已经存在，字段信息将被覆盖，请检查确认！***</font>\r\n");
                // 基础数据配置的信息修改
                if (databaseMap.containsKey(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName())) {
                    DataBaseVo vo = new DataBaseVo();
                    vo.setSql("ALTER TABLE " + ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName() + sqlScript.getVersionSuffix()
                            + " MODIFY COLUMN " + detail.getColumnName().toUpperCase() + " " + TableInfoUtil.handleCloumMysql(detailOldOne, true) +
                            (StringUtils.isNotEmpty(detail.getColumnChineseName()) ? " COMMENT '" + detail.getColumnChineseName() + "'" : "") + ";");
                    vo.setTableName(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName());
                    baseVoList.add(vo);
                }
            } else {
                TableDetail detail = this.getTableDetail(definition, table.getId(), sequence, sqlScript);
                SQLCharExpr expr = (SQLCharExpr) definition.getComment();
                if (null != expr) {
                    String columnChineseName = expr.getText();
                    if (StringUtils.isBlank(columnChineseName)) {
                        throw new BusinessException("增加字段的表没有注释信息，请检查！" + addColumn.getParent());
                    }
                    detail.setColumnChineseName(columnChineseName);
                }
                detail.setCreateBy(sqlScript.getCreateBy());
                detail.setCreateTime(new Date());
                detail.setVersion(sqlScript.getVersion());
                tableDetailMapper.insert(detail);
                mapInfo.put(detail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                mapInfoDemandBugInfo.put(detail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                mapInfoDemandBugInfo.put(detail.getTableId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                // 基础数据配置的信息修改
                if (databaseMap.containsKey(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName())) {
                    DataBaseVo vo = new DataBaseVo();
                    vo.setSql("ALTER TABLE " + ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName() + sqlScript.getVersionSuffix()
                            + " ADD COLUMN " + detail.getColumnName().toUpperCase() + " " + TableInfoUtil.handleCloumMysql(detail, true) +
                            (StringUtils.isNotEmpty(detail.getColumnChineseName()) ? " COMMENT '" + detail.getColumnChineseName() + "'" : "") + ";");
                    vo.setTableName(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName());
                    baseVoList.add(vo);
                }
            }
        }
    }

    /**
     * 修改字段信息
     *
     * @param item
     * @param sqlScript
     * @param mapInfo
     * @return
     */
    private void oracleAlterTableModify(SQLAlterTableItem item, SqlScript sqlScript, Map<String, String> mapInfo,
                                        Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo, String checkVersion,
                                        Map<String, String> databaseMap, List<DataBaseVo> baseVoList) throws
            Exception {
        OracleAlterTableModify modifyColumn = (OracleAlterTableModify) item;
        SQLAlterTableStatement statement = (SQLAlterTableStatement) modifyColumn.getParent();
        SQLExprTableSource exprTableSource = statement.getTableSource();
        this.checkTableAlias(exprTableSource);
        String tableName = exprTableSource.getName().getSimpleName(); //表名
        Table table = this.getTableInfo(tableName);
        List<SQLColumnDefinition> list = modifyColumn.getColumns();
        for (SQLColumnDefinition definition : list) {
            TableDetail detail = this.getTableDetail(definition, table.getId(), 1, sqlScript, false);
            // 查询字段是否存在
            QueryWrapper<TableDetail> wrapper = new QueryWrapper<>();
            wrapper.eq("TABLE_ID", table.getId());
            wrapper.eq("COLUMN_NAME", detail.getColumnName());
            TableDetail detailOld = tableDetailMapper.selectOne(wrapper);
            if (null == detailOld) {
                throw new BusinessException("修改的字段在表中不存在，请检查！" + modifyColumn.getParent());
            }
            if (!this.checkVersion(detailOld.getVersion(), checkVersion)) {
                this.checkTableLength(detailOld, detail, tableName);
            }
            SQLCharExpr expr = (SQLCharExpr) definition.getComment();
            if (null != expr && StringUtils.isBlank(expr.getText())) {
                String columnChineseName = expr.getText(); // 修改的是否中文注释可以为空
                detailOld.setColumnChineseName(columnChineseName);
            }
            // 是否主键，为空的判断
            List<SQLColumnConstraint> constraintList = definition.getConstraints();
            if (!CollectionUtils.isEmpty(constraintList)) {
                for (SQLColumnConstraint constraint : constraintList) {
                    if (null == constraint) {
                        continue;
                    }
                    if (constraint instanceof SQLNotNullConstraint) {
                        detailOld.setColumnNull(2);
                    }
                    if (constraint instanceof SQLNullConstraint) {
                        detailOld.setColumnNull(1);
                    }
                    if (constraint instanceof SQLColumnPrimaryKey) {
                        detailOld.setPrimaryKey(1);
                    }
                }
            }
            if (null != detail.getColumnType()) {
                detailOld.setColumnType(detail.getColumnType());
            }
            if (null != detail.getColumnLength()) {
                detailOld.setColumnLength(detail.getColumnLength());
            }
            if (null != detail.getColumnDecimal()) {
                detailOld.setColumnDecimal(detail.getColumnDecimal());
            }
            if (StringUtils.isNotBlank(detail.getColumnDefault())) {
                detailOld.setColumnDefault(detail.getColumnDefault());
            }
            detailOld.setUpdateBy(sqlScript.getCreateBy());
            detailOld.setUpdateTime(new Date());
            detailOld.setVersion(sqlScript.getVersion());
            mapInfo.put(detailOld.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
            mapInfoDemandBugInfo.put(detailOld.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
            // 添加表字段，把表也放到对应得所属报表，模块，客户
            // mapInfo.put(table.getId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            mapInfoDemandBugInfo.put(detailOld.getTableId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            tableDetailMapper.updateById(detailOld);
            // 基础数据配置的信息修改
            if (databaseMap.containsKey(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName())) {
                DataBaseVo vo = new DataBaseVo();
                vo.setSql("ALTER TABLE " + ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName() + sqlScript.getVersionSuffix()
                        + " MODIFY COLUMN " + detailOld.getColumnName().toUpperCase() + " " + TableInfoUtil.handleCloumMysql(detailOld, true) +
                        (StringUtils.isNotEmpty(detailOld.getColumnChineseName()) ? " COMMENT '" + detailOld.getColumnChineseName() + "'" : "") + ";");
                vo.setTableName(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName());
                baseVoList.add(vo);
            }
        }
    }

    /**
     * 字段长度和精度的校验
     * vacher2 到nvacher2 不受类型影响
     *
     * @param detailOld
     * @param detail
     * @param tableName
     */
    private void checkTableLength(TableDetail detailOld, TableDetail detail, String tableName) {
        if (StringUtils.isNull(detailOld) || StringUtils.isNull(detail)) {
            return;
        }
        // 类型一致的情况  (vacher2 到nvacher2 不受类型影响)
        if ((detailOld.getColumnType() == detail.getColumnType()) ||
                (detailOld.getColumnType() == 1 && detail.getColumnType() == 9)
        ) {
            int oldColumnLength = StringUtils.isNotNull(detailOld.getColumnLength()) ? detailOld.getColumnLength() : 0;
            int columnLength = StringUtils.isNotNull(detail.getColumnLength()) ? detail.getColumnLength() : 0;
            if (columnLength < oldColumnLength) { // 字段长度小于原来得长度
                throw new BusinessException("表【" + tableName + "】字段【" + detailOld.getColumnName() + "】长度小于原来得长度" +
                        "原来长度为【" + oldColumnLength + "】现在长度为【" + columnLength + "】，请检查确认！***\r\n");
            }
            int oldColumnDecimal = StringUtils.isNotNull(detailOld.getColumnDecimal()) ? detailOld.getColumnDecimal() : 0;
            int columnDecimal = StringUtils.isNotNull(detail.getColumnDecimal()) ? detail.getColumnDecimal() : 0;
            if (columnDecimal < oldColumnDecimal) { // 字段精度小于原来得长度
                throw new BusinessException("表【" + tableName + "】字段【" + detailOld.getColumnName() + "】精度小于原来得精度" +
                        "原来精度为【" + oldColumnDecimal + "】现在精度为【" + columnDecimal + "】，请检查确认！***\r\n");
            }
        } else { // 类型变化了
            throw new BusinessException("<font color='red'>***表【" + tableName + "】字段【" + detailOld.getColumnName() + "】类型发生变化" +
                    "，如果确认要修改请联系管理员！***</font>\r\n");
        }
    }

    /**
     * 删除主键
     *
     * @param item
     * @param sqlScript
     * @param mapInfo
     * @return
     * @throws Exception
     */
    private void sqlAlterTableDropConstraint(SQLAlterTableItem item, SqlScript
            sqlScript, Map<String, String> mapInfo, Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo,
                                             Map<String, String> databaseMap, List<DataBaseVo> baseVoList) throws Exception {
        SQLAlterTableDropConstraint dropConstraint = (SQLAlterTableDropConstraint) item;
        SQLAlterTableStatement tableStatement = (SQLAlterTableStatement) dropConstraint.getParent();
        SQLExprTableSource exprTableSource = tableStatement.getTableSource();
        this.checkTableAlias(exprTableSource);
        // 表名
        Table table = this.getTableInfo(tableStatement.getTableName());
        List<SQLAlterTableItem> itemList = tableStatement.getItems();
        for (SQLAlterTableItem tableItem : itemList) {
            SQLAlterTableDropConstraint constraint = (SQLAlterTableDropConstraint) tableItem;
            if (StringUtils.isBlank(constraint.getConstraintName().getSimpleName())) {
                throw new BusinessException("没有获取到删除主键的字段信息，请检查！" + tableStatement.getParent());
            }
            // 获取字段
            QueryWrapper<TableDetail> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("TABLE_ID", table.getId());
            queryWrapper.eq("COLUMN_NAME", constraint.getConstraintName().getSimpleName());
            TableDetail tableDetail = tableDetailMapper.selectOne(queryWrapper);
            if (null == tableDetail || StringUtils.isBlank(tableDetail.getId())) {
                throw new BusinessException("没有获取到删除主键的字段信息，请检查！" + tableStatement.getParent());
            }
            tableDetail.setPrimaryKey(2);
            tableDetail.setUpdateBy(sqlScript.getCreateBy());
            tableDetail.setUpdateTime(new Date());
            tableDetail.setVersion(sqlScript.getVersion());
            tableDetailMapper.updateById(tableDetail);
            mapInfoDemandBugInfo.put(tableDetail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
            mapInfoDemandBugInfo.put(tableDetail.getTableId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            // 基础数据配置的信息修改
            if (databaseMap.containsKey(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName())) {
                DataBaseVo vo = new DataBaseVo();
                vo.setTableName(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName());
                baseVoList.add(vo);
            }
        }
    }

    /**
     * 新增主键信息
     *
     * @param item
     * @param sqlScript
     * @param mapInfo
     * @return
     * @throws Exception
     */
    private void sqlAlterTableAddConstraint(SQLAlterTableItem item, SqlScript
            sqlScript, Map<String, String> mapInfo, Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo,
                                            Map<String, String> databaseMap, List<DataBaseVo> baseVoList) throws Exception {
        SQLAlterTableAddConstraint addConstraint = (SQLAlterTableAddConstraint) item;
        if (addConstraint.getConstraint() instanceof OraclePrimaryKey) { //主键
            OraclePrimaryKey primaryKey = (OraclePrimaryKey) addConstraint.getConstraint();
            SQLAlterTableStatement alterTableStatement = (SQLAlterTableStatement) primaryKey.getParent().getParent();
            SQLExprTableSource exprTableSource = alterTableStatement.getTableSource();
            this.checkTableAlias(exprTableSource);
            Table table = this.getTableInfo(alterTableStatement.getTableSource().getName().getSimpleName()); // 表名
            List<SQLSelectOrderByItem> list = primaryKey.getColumns();
            if (CollectionUtils.isEmpty(list)) {
                throw new BusinessException("没有获取到要添加主键的字段信息，请检查！" + addConstraint.getParent());
            }
            for (SQLSelectOrderByItem orderByItem : list) {
                SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) orderByItem.getExpr();
                // 查询要设置字段主键的字段信息是否存在
                QueryWrapper<TableDetail> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("TABLE_ID", table.getId());
                queryWrapper.eq("COLUMN_NAME", identifierExpr.getName().toUpperCase()); // 字段名称
                TableDetail detail = tableDetailMapper.selectOne(queryWrapper);
                if (null == detail) {
                    throw new BusinessException("添加主键的字段在表结构信息中不存在，请检查！" + addConstraint.getParent());
                }
                detail.setPrimaryKey(1);
                detail.setUpdateBy(sqlScript.getCreateBy());
                detail.setUpdateTime(new Date());
                detail.setVersion(sqlScript.getVersion());
                tableDetailMapper.updateById(detail);
                mapInfoDemandBugInfo.put(detail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                mapInfoDemandBugInfo.put(detail.getTableId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                // 基础数据配置的信息修改
                if (databaseMap.containsKey(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName())) {
                    DataBaseVo vo = new DataBaseVo();
                    vo.setTableName(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName());
                    baseVoList.add(vo);
                }
            }
        } else if (addConstraint.getConstraint() instanceof OracleUnique) { // 索引
            OracleUnique oracleUnique = (OracleUnique) addConstraint.getConstraint();
            SQLAlterTableStatement alterTableStatement = (SQLAlterTableStatement) oracleUnique.getParent().getParent();
            SQLExprTableSource exprTableSource = alterTableStatement.getTableSource();
            this.checkTableAlias(exprTableSource);
            Table table = this.getTableInfo(alterTableStatement.getTableSource().getName().getSimpleName()); // 表名
            SQLIdentifierExpr sqlIdentifierExpr = (SQLIdentifierExpr) oracleUnique.getName();
            String indexName = sqlIdentifierExpr.getName();   // 索引名称
            this.nameCheck(indexName);
            // 查询是否存在该索引名字
            QueryWrapper<TableIndexed> indexedQueryWrapper = new QueryWrapper<>();
            indexedQueryWrapper.eq("TABLE_ID", table.getId());
            indexedQueryWrapper.eq("INDEXED_NAME", indexName);
            indexedQueryWrapper.select("MAX(INDEXED_SEQUENCE) AS INDEXED_SEQUENCE");
            TableIndexed indexed = tableIndexedMapper.selectOne(indexedQueryWrapper);
            if (null != indexed) {
                //throw new BusinessException("语句【" + item + "】已经存在相同的索引名称，请检查！");
                msgInfo.append("<font color='red'>***语句【" + addConstraint.getParent() + "】已经存在相同的索引名称，系统已经跳过，请检查！***</font>").append("\r\n");
                return;
            }
            // 查询最大的索引顺序
            QueryWrapper<TableIndexed> tableIndexedQueryWrapper = new QueryWrapper<>();
            tableIndexedQueryWrapper.eq("TABLE_ID", table.getId());
            tableIndexedQueryWrapper.select("MAX(INDEXED_SEQUENCE) AS INDEXED_SEQUENCE");
            TableIndexed maxSequence = tableIndexedMapper.selectOne(tableIndexedQueryWrapper);
            // 字段名称
            List<SQLSelectOrderByItem> list = oracleUnique.getColumns();
            if (CollectionUtils.isEmpty(list)) {
                throw new BusinessException("语句【" + addConstraint.getParent() + "】没有获取到调整表索引的字段，请检查！");
            }
            int i = 1;
            for (SQLSelectOrderByItem orderByItem : list) {
                SQLIdentifierExpr expr = (SQLIdentifierExpr) orderByItem.getExpr();
                TableIndexed newIndexed = new TableIndexed();
                // 获取索引类型
                newIndexed.setIndexedType(2);
                newIndexed.setId(IdUtils.fastSimpleUUID());
                newIndexed.setTableId(table.getId());
                newIndexed.setIndexedName(indexName);
                newIndexed.setStatus(YssStatusEnum.NORMAL.getCode());
                newIndexed.setCreateBy(sqlScript.getCreateBy());
                newIndexed.setCreateTime(new Date());
                newIndexed.setIndexedColumnName(expr.getName());
                if (null == maxSequence || null == maxSequence.getIndexedSequence()) {
                    newIndexed.setIndexedSequence(1);
                } else {
                    newIndexed.setIndexedSequence(maxSequence.getIndexedSequence() + 1);
                }
                newIndexed.setIndexedColumnSequence(i);
                SQLOrderingSpecification specification = orderByItem.getType();
                if (null != specification && StringUtils.isBlank(specification.name)) { // 排序
                    newIndexed.setIndexedAscDesc(specification.name.toUpperCase());
                }
                i++;
                QueryWrapper<TableIndexed> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("TABLE_ID", table.getId());
                queryWrapper.eq("INDEXED_NAME", indexName);
                queryWrapper.eq("INDEXED_COLUMN_NAME", expr.getName());
                TableIndexed indexedOld = tableIndexedMapper.selectOne(queryWrapper);
                if (null != indexedOld) { // 已经存在索引，修改索引信息
                    //   throw new BusinessException("该索引名称下面已经有该字段存在，请检查！" + statement.getParent());
                    BeanUtils.copyProperties(indexedOld, newIndexed, new String[]{"id", "sequence"});
                    indexedOld.setUpdateBy(sqlScript.getCreateBy());
                    indexedOld.setUpdateTime(new Date());
                    tableIndexedMapper.updateById(indexedOld);
                    mapInfoDemandBugInfo.put(table.getId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                    continue;
                }
                newIndexed.setFileName(sqlScript.getId());
                newIndexed.setCreateBy(sqlScript.getCreateBy());
                newIndexed.setCreateTime(new Date());
                tableIndexedMapper.insert(newIndexed);
                mapInfoDemandBugInfo.put(table.getId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            }
        } else {
            throw new BusinessException("语句【" + item + "】系统还不持支持改方法，请联系管理员");
        }
    }

    /**
     * 修改表字段名称
     *
     * @param item
     * @param sqlScript
     * @param mapInfo
     * @return
     * @throws Exception
     */
    private void sqlAlterTableRenameColumn(SQLAlterTableItem item, SqlScript
            sqlScript, Map<String, String> mapInfo, Map<String, String> mapInfoDemandBugInfo,
                                           StringBuffer msgInfo, String checkVersion,
                                           Map<String, String> databaseMap, List<DataBaseVo> baseVoList) throws Exception {
        SQLAlterTableRenameColumn renameColumn = (SQLAlterTableRenameColumn) item;
        SQLAlterTableStatement statement = (SQLAlterTableStatement) item.getParent();
        String tableName = statement.getTableSource().getName().getSimpleName();
        SQLExprTableSource exprTableSource = statement.getTableSource();
        this.checkTableAlias(exprTableSource);
        Table table = this.getTableInfo(tableName);
        SQLIdentifierExpr expr = (SQLIdentifierExpr) renameColumn.getColumn(); // 修改前的字段
        if (null == expr || StringUtils.isBlank(expr.getName())) {
            throw new BusinessException("没有获取到语句里修改前的表字段信息，请检查！" + renameColumn.getParent());
        }
        String columnName = expr.getName();
        SQLIdentifierExpr renameExpr = (SQLIdentifierExpr) renameColumn.getTo();  //修改后的字段
        if (null == expr || StringUtils.isBlank(renameExpr.getName())) {
            throw new BusinessException("没有获取到要修改的字段的名称，请检查！" + renameColumn.getParent());
        }
        String renameName = renameExpr.getName();
        // 查询修改前的字段是否存在
        QueryWrapper<TableDetail> wrapper = new QueryWrapper<>();
        wrapper.eq("TABLE_ID", table.getId());
        wrapper.eq("COLUMN_NAME", columnName.toUpperCase());
        TableDetail detail = tableDetailMapper.selectOne(wrapper);
        if (null == detail) {
            throw new BusinessException("没有获取到修改前的表字段信息，请检查！" + renameColumn.getParent());
        }
        if (!this.checkVersion(detail.getVersion(), checkVersion)) {
            throw new BusinessException("修改表对应字段跨版本，系统限制不允许修改，请检查！" + renameColumn.getParent());
        }
        TableDetail newDetail = new TableDetail();
        BeanUtils.copyProperties(detail, newDetail);
        detail.setStatus(YssStatusEnum.DELETED.getCode()); // 原来的字段设置为已删除
        detail.setUpdateBy(sqlScript.getCreateBy());
        detail.setUpdateTime(new Date());
        detail.setVersion(sqlScript.getVersion());
        tableDetailMapper.updateById(detail);
        mapInfoDemandBugInfo.put(detail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
        // 查询修改前的字段是否存在
        QueryWrapper<TableDetail> wrapperOld = new QueryWrapper<>();
        wrapperOld.eq("TABLE_ID", table.getId());
        wrapperOld.eq("COLUMN_NAME", renameName.toUpperCase());
        TableDetail detailOld = tableDetailMapper.selectOne(wrapperOld);
        if (null != detailOld) { // 已经存在，就直接修改状态
            detailOld.setStatus(YssStatusEnum.NORMAL.getCode());
            detailOld.setColumnName(renameName);
            detailOld.setUpdateBy(sqlScript.getCreateBy());
            detailOld.setUpdateTime(new Date());
            detailOld.setVersion(sqlScript.getVersion());
            detailOld.setOriginalColumnName(columnName);
            tableDetailMapper.updateById(detailOld);
            //  mapInfo.put(detailOld.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
            mapInfoDemandBugInfo.put(detailOld.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
            mapInfoDemandBugInfo.put(detailOld.getTableId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            // 基础数据配置的信息修改
            if (databaseMap.containsKey(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName())) {
                DataBaseVo vo = new DataBaseVo();
                vo.setSql("ALTER TABLE " + ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName() + sqlScript.getVersionSuffix()
                        + " MODIFY COLUMN " + detailOld.getColumnName().toUpperCase() + " " + TableInfoUtil.handleCloumMysql(detailOld, true) +
                        (StringUtils.isNotEmpty(detailOld.getColumnChineseName()) ? " COMMENT '" + detailOld.getColumnChineseName() + "'" : "") + ";");
                vo.setTableName(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName());
                baseVoList.add(vo);
            }
        } else {
            newDetail.setStatus(YssStatusEnum.NORMAL.getCode());
            newDetail.setId(IdUtils.fastSimpleUUID());
            newDetail.setColumnName(renameName);
            newDetail.setCreateBy(sqlScript.getCreateBy());
            newDetail.setCreateTime(new Date());
            newDetail.setVersion(sqlScript.getVersion());
            newDetail.setOriginalColumnName(columnName);
            newDetail.setColumnChineseName(detail.getColumnChineseName()); //中文描述还是取之前的
            tableDetailMapper.insert(newDetail);
            // mapInfo.put(newDetail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
            mapInfoDemandBugInfo.put(newDetail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
            mapInfoDemandBugInfo.put(newDetail.getTableId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            // 基础数据配置的信息修改
            if (databaseMap.containsKey(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName())) {
                DataBaseVo vo = new DataBaseVo();
                vo.setSql("ALTER TABLE " + ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName() + sqlScript.getVersionSuffix()
                        + " CHANGE `" + columnName.toUpperCase() + "`  `" + renameName.toUpperCase()
                        + "` " + TableInfoUtil.handleCloumMysql(newDetail, true) + ";");
                vo.setTableName(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName());
                baseVoList.add(vo);
            }
        }
    }

    /**
     * 删除表字段
     *
     * @param item
     * @param sqlScript
     * @param mapInfo
     * @return
     * @throws Exception
     */
    private void sqlAlterTableDropColumnItem(SQLAlterTableItem item, SqlScript
            sqlScript, Map<String, String> mapInfo, Map<String, String> mapInfoDemandBugInfo, String checkVersion,
                                             Map<String, String> databaseMap, List<DataBaseVo> baseVoList) throws Exception {
        SQLAlterTableDropColumnItem dropColumn = (SQLAlterTableDropColumnItem) item;
        SQLAlterTableStatement statement = (SQLAlterTableStatement) dropColumn.getParent();
        String tableName = statement.getTableSource().getName().getSimpleName();
        Table table = this.getTableInfo(tableName);
        List<SQLName> list = dropColumn.getColumns();
        if (CollectionUtils.isEmpty(list)) {
            throw new BusinessException("没有获取到要删除表字段的信息，请检查！" + statement);
        }
        for (SQLName sqlName : list) {
            SQLIdentifierExpr expr = (SQLIdentifierExpr) sqlName;
            String columnName = expr.getName();
            QueryWrapper<TableDetail> wrapper = new QueryWrapper<>();
            wrapper.eq("TABLE_ID", table.getId());
            wrapper.eq("COLUMN_NAME", columnName.toUpperCase());
            TableDetail detail = tableDetailMapper.selectOne(wrapper);
            if (null == detail) {
                throw new BusinessException("没有获取到删除表对应的字段信息，请检查！" + statement);
            }
            if (!this.checkVersion(detail.getVersion(), checkVersion)) {
                throw new BusinessException("删除表对应字段跨版本，系统限制不允许删除，请检查！" + statement);
            }
            detail.setUpdateBy(sqlScript.getCreateBy());
            detail.setUpdateTime(new Date());
            detail.setVersion(sqlScript.getVersion());
            detail.setStatus(YssStatusEnum.DELETED.getCode());
            mapInfoDemandBugInfo.put(detail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
            mapInfoDemandBugInfo.put(detail.getTableId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            tableDetailMapper.updateById(detail);
            // 基础数据配置的信息修改
            if (databaseMap.containsKey(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName())) {
                DataBaseVo vo = new DataBaseVo();
                vo.setSql("ALTER TABLE " + ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName() + sqlScript.getVersionSuffix() + " DROP COLUMN " + columnName.toUpperCase());
                vo.setTableName(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName());
                baseVoList.add(vo);
            }
        }
    }

    /**
     * 修改表名
     *
     * @param item
     * @param sqlScript
     * @param mapInfo
     * @return
     * @throws Exception
     */
    private void sqlAlterTableRename(SQLAlterTableItem item, SqlScript sqlScript, Map<String, String> mapInfo,
                                     Map<String, String> mapInfoDemandBugInfo,
                                     StringBuffer msgInfo, String checkVersion,
                                     Map<String, String> databaseMap, List<DataBaseVo> baseVoList) throws
            Exception {
        SQLAlterTableRename tableRename = (SQLAlterTableRename) item;
        SQLAlterTableStatement statement = (SQLAlterTableStatement) tableRename.getParent();
        SQLExprTableSource exprTableSource = statement.getTableSource();
        this.checkTableAlias(exprTableSource);
        String tableName = statement.getTableSource().getName().getSimpleName(); // 表名
        Table table = this.getTableInfo(tableName);
        if (!this.checkVersion(table.getVersion(), checkVersion)) {
            throw new BusinessException("修改表名跨版本，系统限制不允许修改，请检查！" + statement.toString());
        }
        SQLExprTableSource tableSource = tableRename.getTo(); //要修改成的表名
        this.checkTableAlias(tableSource);
        SQLIdentifierExpr expr = (SQLIdentifierExpr) tableSource.getExpr();
        String tableNameNew = expr.getName();// 要修改成的表名
        if (null == expr || StringUtils.isBlank(expr.getName())) {
            throw new BusinessException("没有获取到修改的表名信息，请检查！" + statement.getParent());
        }
        // 获取要修改的表名是不是已经存在
        QueryWrapper<Table> wrapper = new QueryWrapper<>();
        wrapper.eq("NAME", tableNameNew.toUpperCase());
        Table tableNew = tableMapper.selectOne(wrapper);
        if (null != tableNew) { // 已经存在表名
            throw new BusinessException("要修改的表名，已经存在了，请检查！" + statement.getParent());
        }
        table.setName(expr.getName());
        table.setUpdateBy(sqlScript.getCreateBy());
        table.setUpdateTime(new Date());
        table.setVersion(sqlScript.getVersion());
        //  table.setFileName(sqlScript.getId());
        table.setOriginalTableName(table.getName());
        tableMapper.updateById(table);
        mapInfo.put(table.getId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
        mapInfoDemandBugInfo.put(table.getId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
        // 基础数据配置的信息修改
        if (databaseMap.containsKey(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName())) {
            DataBaseVo vo = new DataBaseVo();
            vo.setSql("RENAME  " + table.getName().toUpperCase() + sqlScript.getVersionSuffix() + " TO " + ReportWorldEnum.RW_DB_SUFFIX.getCode() + expr.getName() + sqlScript.getVersionSuffix() + " ;");
            vo.setTableName(ReportWorldEnum.RW_DB_SUFFIX.getCode() + table.getName());
            baseVoList.add(vo);
        }
    }

    /**
     * 增加表注释或者增加列注释信息
     *
     * @param stmt
     * @param sqlScript
     * @return
     */
    private void sqlCommentStatement(SQLStatement stmt, SqlScript sqlScript, Map<String, String> mapInfo,
                                     Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo) throws Exception {
        // List<Table> tableList = new ArrayList<>();
        //  List<TableDetail> tableDetailList = new ArrayList<>();
        try {
            SQLCommentStatement statement = (SQLCommentStatement) stmt;
            // 增加表说明还是列说明
            SQLCommentStatement.Type type = statement.getType();
            if (null == type) {
                throw new BusinessException("增加表注释或者增加列注释信息没有获取到要添加说明的列或者表类型，请检查！" + statement.toString());
            }
            SQLExprTableSource tableSource = statement.getOn();
            if (null == tableSource) {
                throw new BusinessException("增加表注释或者增加列注释信息没有获取到要对应的表名信息，请检查！" + statement.toString());
            }
            // 增加表说明
            if ("TABLE".equals(type.name())) {
                if (null == statement.getComment()) {
                    throw new BusinessException("表注释信息不能为空，请检查！" + statement.getParent());
                }
                if (statement.getComment() instanceof SQLNullExpr) {
                    throw new BusinessException("表段注释信息不能为空，请检查！" + statement.getParent());
                }
                SQLCharExpr expr = (SQLCharExpr) statement.getComment(); // 表的中文说明
                String tableName = tableSource.getName().getSimpleName(); //要增加的表名
                Table table = this.getTableInfo(tableName);
                String chineseName = expr.getText();
                table.setChineseName(chineseName);
                table.setFileName(sqlScript.getId());
                table.setVersion(sqlScript.getVersion());
                table.setUpdateBy(sqlScript.getCreateBy());
                table.setUpdateTime(new Date());
                // tableList.add(table);  // 修改表说明
                tableMapper.updateById(table);
                //  mapInfo.put(table.getId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                mapInfoDemandBugInfo.put(table.getId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            } else if ("COLUMN".equals(type.name())) {
                if (null == statement.getComment()) {
                    throw new BusinessException("字段注释信息不能为空，请检查！" + statement.toString());
                }
                if (statement.getComment() instanceof SQLNullExpr) {
                    throw new BusinessException("字段注释信息不能为空，请检查！" + statement.toString());
                }
                SQLCharExpr expr = (SQLCharExpr) statement.getComment(); // 字段的中文说明
                SQLPropertyExpr propertyExpr = (SQLPropertyExpr) tableSource.getExpr();
                SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) propertyExpr.getOwner();
                String tableName = identifierExpr.getName();
                Table table = this.getTableInfo(tableName);
                String columnName = tableSource.getName().getSimpleName(); //要增加的字段名称
                if (StringUtils.isBlank(columnName)) {
                    throw new BusinessException("增加列注释信息要添加字段说明的表字段信息不存在，请检查！" + statement.toString());
                }
                QueryWrapper<TableDetail> detailQueryWrapper = new QueryWrapper<>();
                detailQueryWrapper.eq("TABLE_ID", table.getId());
                detailQueryWrapper.eq("COLUMN_NAME", columnName.toUpperCase());
                TableDetail detail = tableDetailMapper.selectOne(detailQueryWrapper);
                if (null == detail) {
                    throw new BusinessException("增加列注释信息要添加字段说明的表字段信息不存在，请检查！" + statement.toString());
                }
                String chineseName = expr.getText();
                detail.setColumnChineseName(chineseName); // 字段说明
                if (StringUtils.isNotBlank(chineseName) && chineseName.indexOf("【") > -1 && chineseName.indexOf("】") > -1) {
                    String name = StringUtils.substring(chineseName, 0, chineseName.indexOf("【"));
                    detail.setColumnChineseName(name); // 字段说明
                    String codeName = StringUtils.substring(chineseName, chineseName.indexOf("【") + 1, chineseName.indexOf("】"));
                    detail.setCodeName(codeName);
                }
                detail.setFileName(sqlScript.getId());
                detail.setVersion(sqlScript.getVersion());
                // mapInfo.put(detail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                mapInfoDemandBugInfo.put(detail.getId(), ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode());
                //tableDetailList.add(detail);
                detail.setUpdateBy(sqlScript.getCreateBy());
                detail.setUpdateTime(new Date());
                tableDetailMapper.updateById(detail);
            }
         /*   if (!CollectionUtils.isEmpty(tableList)) {
                tableMapper.updateBatchById(tableList);
            }
            if (!CollectionUtils.isEmpty(tableDetailList)) {
                tableDetailMapper.updateBatchById(tableDetailList);
            }*/
        } catch (Exception ex) {
            log.error(ex.getMessage());
            throw new BusinessException("增加表注释或者增加列注释信息出错！" + ex.getMessage());
        }
    }

    /**
     * 创建索引语句解析
     *
     * @param stmt
     * @param sqlScript
     * @param mapInfo
     * @return
     */
    private void sqlCreateIndexStatement(SQLStatement stmt, SqlScript
            sqlScript, Map<String, String> mapInfo, Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo) throws Exception {
        SQLCreateIndexStatement statement = (SQLCreateIndexStatement) stmt;
        SQLExprTableSource tableSource = (SQLExprTableSource) statement.getTable();
        this.checkTableAlias(tableSource);
        SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) tableSource.getExpr();
        String tableName = identifierExpr.getName(); // 表名
        if (StringUtils.isBlank(tableName)) {
            throw new BusinessException("没有获取到创建索引的表信息，请检查！" + statement.getParent());
        }
        Table table = this.getTableInfo(tableName);
        SQLIdentifierExpr sqlIdentifierExpr = (SQLIdentifierExpr) statement.getName();
        String indexName = sqlIdentifierExpr.getName();   // 索引名称
        this.nameCheck(indexName);
        // 查询是否存在该索引名字
        QueryWrapper<TableIndexed> indexedQueryWrapper = new QueryWrapper<>();
        indexedQueryWrapper.eq("TABLE_ID", table.getId());
        indexedQueryWrapper.eq("INDEXED_NAME", indexName);
        indexedQueryWrapper.select("MAX(INDEXED_SEQUENCE) AS INDEXED_SEQUENCE");
        TableIndexed indexed = tableIndexedMapper.selectOne(indexedQueryWrapper);
        if (null != indexed) {
            // throw new BusinessException("已经存在相同的索引名称，请检查！" + statement.getParent());
            msgInfo.append("***语句【" + stmt + "】已经存在相同的索引名称，系统已经跳过，请检查！***").append("\r\n");
            return;
        }
        // 查询最大的索引顺序
        QueryWrapper<TableIndexed> tableIndexedQueryWrapper = new QueryWrapper<>();
        tableIndexedQueryWrapper.eq("TABLE_ID", table.getId());
        tableIndexedQueryWrapper.select("MAX(INDEXED_SEQUENCE) AS INDEXED_SEQUENCE");
        TableIndexed maxSequence = tableIndexedMapper.selectOne(tableIndexedQueryWrapper);
        // 字段名称
        List<SQLSelectOrderByItem> list = statement.getItems();
        if (CollectionUtils.isEmpty(list)) {
            throw new BusinessException("没有获取到调整表索引的字段，请检查！" + statement.getParent());
        }
        int i = 1;
        for (SQLSelectOrderByItem item : list) {
            SQLIdentifierExpr expr = (SQLIdentifierExpr) item.getExpr();
            TableIndexed newIndexed = new TableIndexed();
            // 获取索引类型
            OracleCreateIndexStatement indexStatement = (OracleCreateIndexStatement) expr.getParent().getParent();
            newIndexed.setIndexedType(1);
            if (null != indexStatement && StringUtils.isNotBlank(indexStatement.getType())) {
                String type = indexStatement.getType().toUpperCase();
                if ("UNIQUE".equals(type)) {
                    newIndexed.setIndexedType(2);
                } else {
                    throw new BusinessException("系统还没有改索引类型，请管理员添加对应的索引类型！" + statement.getParent());
                }
            }
            String id = IdUtils.fastSimpleUUID();
            newIndexed.setId(id);
            newIndexed.setTableId(table.getId());
            newIndexed.setIndexedName(indexName);
            newIndexed.setStatus(YssStatusEnum.NORMAL.getCode());
            newIndexed.setCreateBy(sqlScript.getCreateBy());
            newIndexed.setCreateTime(new Date());
            newIndexed.setIndexedColumnName(expr.getName());
            if (null == maxSequence || null == maxSequence.getIndexedSequence()) {
                newIndexed.setIndexedSequence(1);
            } else {
                newIndexed.setIndexedSequence(maxSequence.getIndexedSequence() + 1);
            }
            newIndexed.setIndexedColumnSequence(i);
            SQLOrderingSpecification specification = item.getType();
            if (null != specification && StringUtils.isBlank(specification.name)) { // 排序
                newIndexed.setIndexedAscDesc(specification.name.toUpperCase());
            }
            i++;
            QueryWrapper<TableIndexed> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("TABLE_ID", table.getId());
            queryWrapper.eq("INDEXED_NAME", indexName);
            queryWrapper.eq("INDEXED_COLUMN_NAME", expr.getName());
            TableIndexed indexedOld = tableIndexedMapper.selectOne(queryWrapper);
            if (null != indexedOld) { // 已经存在索引，修改索引信息
                //   throw new BusinessException("该索引名称下面已经有该字段存在，请检查！" + statement.getParent());
                BeanUtils.copyProperties(indexedOld, newIndexed, new String[]{"id", "sequence"});
                indexedOld.setUpdateBy(sqlScript.getCreateBy());
                indexedOld.setUpdateTime(new Date());
                tableIndexedMapper.updateById(indexedOld);
                mapInfoDemandBugInfo.put(indexedOld.getId(), ReportWorldEnum.REPORT_TABLE_INDEXED_CODE.getCode());
                continue;
            }
            newIndexed.setFileName(sqlScript.getId());
            tableIndexedMapper.insert(newIndexed);
            mapInfoDemandBugInfo.put(id, ReportWorldEnum.REPORT_TABLE_INDEXED_CODE.getCode());
        }
    }


    /**
     * 删除索引  drop index
     *
     * @param stmt
     * @param sqlScript
     * @param mapInfo
     * @return
     */
    private void sqlDropIndexStatement(SQLStatement stmt, SqlScript
            sqlScript, Map<String, String> mapInfo, Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo) throws Exception {
        SQLDropIndexStatement statement = (SQLDropIndexStatement) stmt;
        String indexName = statement.getIndexName().getSimpleName();  // 删除的索引名称
        if (StringUtils.isBlank(indexName)) {
            throw new BusinessException("没有获取到要删除的索引名称，请检查！");
        }
        QueryWrapper<TableIndexed> wrapper = new QueryWrapper<>();
        wrapper.eq("INDEXED_NAME", indexName);
        List<TableIndexed> list = tableIndexedMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            throw new BusinessException("要删除的索引" + indexName + "不存在，请检查！");
        }
        for (TableIndexed indexed : list) {
            if (null == indexed || StringUtils.isBlank(indexed.getId())) {
                continue;
            }
            // 修改为删除状态
            indexed.setUpdateBy(sqlScript.getCreateBy());
            indexed.setUpdateTime(new Date());
            indexed.setStatus(YssStatusEnum.DELETED.getCode());
            indexed.setUpdateBy(sqlScript.getCreateBy());
            indexed.setUpdateTime(new Date());
            tableIndexedMapper.updateById(indexed);
            mapInfoDemandBugInfo.put(indexed.getTableId(), ReportWorldEnum.REPORT_TABLE_CODE.getCode());
        }
    }


    /**
     * 插入语句解析
     *
     * @param stmt
     * @param sqlScript
     * @return
     */
    private void sqlInsertStatement(SQLStatement stmt, SqlScript
            sqlScript, Map<String, String> mapInfo, Connection connection,
                                    Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo, Map<String, SqlScriptVO> sqlVOMap) throws Exception {
        this.sqlInsertStatement(stmt, sqlScript, mapInfo, connection, mapInfoDemandBugInfo, msgInfo, null, sqlVOMap);
    }

    /**
     * 插入语句解析
     *
     * @param stmt
     * @param sqlScript
     * @return
     */
    private void sqlInsertStatement(SQLStatement stmt, SqlScript sqlScript, Map<String, String> mapInfo, Connection connection,
                                    Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo, Map<String, Object> mapDeclare, Map<String, SqlScriptVO> sqlVOMap) throws Exception {
        try {
            // 存在字段名称和字段信息
            Map<String, List<Object>> mapCoulmnName = new HashMap<>();
            Map<String, List<List<Object>>> mapCoulmnValue = new HashMap<>();
            SQLInsertStatement statement = (SQLInsertStatement) stmt;
            //获取表名
            SQLExprTableSource tableSource = statement.getTableSource();
            this.checkTableAlias(tableSource);
            SQLIdentifierExpr expr = (SQLIdentifierExpr) tableSource.getExpr();
            String tableName = expr.getName(); // 表名
            if (StringUtils.isBlank(tableName)) {
                throw new BusinessException("插入语句中没有获取到表名，请检查！" + statement.getParent());
            }
            tableName = tableName.toUpperCase();
            List<SQLExpr> sqlExprList = statement.getColumns();
            if (CollectionUtils.isEmpty(sqlExprList)) {
                throw new BusinessException("插入语句中没有获取到插入字段的信息，请检查！" + statement.getParent());
            }
            List<Object> listCoulmnName = new ArrayList<>();
            for (SQLExpr sqlExpr : sqlExprList) {
                if (sqlExpr instanceof SQLIdentifierExpr) {
                    SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) sqlExpr;
                    String name = identifierExpr.getName();
                    listCoulmnName.add(name.toUpperCase());
                }
                if (sqlExpr instanceof SQLCharExpr) { //关键字带了引号的处理
                    SQLCharExpr sqlCharExpr = (SQLCharExpr) sqlExpr;
                    String name = sqlCharExpr.getText().replaceAll("'", "").replaceAll("`", "");
                    listCoulmnName.add(name.toUpperCase());
                }
            }
            // 已经存在的要和之前的字段个数比较时候一致
            if (mapCoulmnName.containsKey(tableName) && mapCoulmnName.get(tableName).size() != listCoulmnName.size()) {
                throw new BusinessException("相同插入语句的字段个数不一致，请检查！" + statement.getParent());
            }
            mapCoulmnName.put(tableName, listCoulmnName);
            List<SQLInsertStatement.ValuesClause> valuesClauseList = statement.getValuesList();
            if (CollectionUtils.isEmpty(valuesClauseList)) {
                throw new BusinessException("插入语句中没有获取到插入字段的值信息，请检查！" + statement.getParent());
            }
            // 值可以是多条数据以前插入
            for (SQLInsertStatement.ValuesClause valuesClause : valuesClauseList) {
                List<SQLExpr> list = valuesClause.getValues();
                if (sqlExprList.size() != list.size()) {
                    throw new BusinessException("插入语句中插入字段个数和值的个数不一致，请检查！" + statement.getParent());
                }
                List<Object> objectList = new ArrayList<>();
                // 字段对应的值
                List<List<Object>> listCoulmnValue = null;
                if (!mapCoulmnValue.containsKey(tableName)) {
                    listCoulmnValue = new ArrayList<>();
                } else {
                    listCoulmnValue = mapCoulmnValue.get(tableName);
                }
                for (SQLExpr sqlExpr : list) {
                    if (sqlExpr instanceof SQLNullExpr) { //字符类型
                        objectList.add(null);
                        continue;
                    }
                    if (sqlExpr instanceof SQLCharExpr) { //字符类型
                        SQLCharExpr sqlCharExpr = (SQLCharExpr) sqlExpr;
                        if (null != sqlCharExpr) {
                            objectList.add(sqlCharExpr.getText());
                        }
                        continue;
                    }
                    if (sqlExpr instanceof SQLIntegerExpr) { //字符类型
                        SQLIntegerExpr sqlIntegerExpr = (SQLIntegerExpr) sqlExpr;
                        if (null != sqlIntegerExpr) {
                            objectList.add(sqlIntegerExpr.getNumber());
                        }
                        continue;
                    }
                    if (sqlExpr instanceof SQLMethodInvokeExpr) { // 方法类型 如 sys_guid()
                        objectList.add(this.checkSQLMethodInvokeExpr(sqlExpr));
                        continue;
                    }
                    if (sqlExpr instanceof OracleSysdateExpr) { // ORACLE 的 SYSDATE默认值
                        OracleSysdateExpr invokeExpr = (OracleSysdateExpr) sqlExpr;
                        if (null != invokeExpr) {
                            objectList.add(DateUtils.dateToStrByFormat(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS));
                        }
                        continue;
                    }
                    if (sqlExpr instanceof SQLNumberExpr) { //字符类型
                        SQLNumberExpr sqlNumberExpr = (SQLNumberExpr) sqlExpr;
                        if (null != sqlNumberExpr) {
                            objectList.add(sqlNumberExpr.getNumber());
                        }
                        continue;
                    }
                    if (sqlExpr instanceof SQLTimestampExpr) {
                        SQLTimestampExpr invokeExpr = (SQLTimestampExpr) sqlExpr;
                        if (null != invokeExpr) {
                            objectList.add(invokeExpr.getLiteral());
                        }
                        continue;
                    }
                    if (sqlExpr instanceof SQLBinaryOpExpr) { // 拼接的类型  例如 '请输入' || '管理人统一社会信用代码'
                        SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) sqlExpr;
                        objectList.add(binaryOpExpr.getLeft() + "||" + binaryOpExpr.getRight());
                        continue;
                    }
                    if (sqlExpr instanceof SQLIdentifierExpr && !CollectionUtils.isEmpty(mapDeclare)) {
                        SQLIdentifierExpr invokeExpr = (SQLIdentifierExpr) sqlExpr;
                        if (null != invokeExpr && mapDeclare.containsKey(invokeExpr.getSimpleName())) {
                            objectList.add(mapDeclare.get(invokeExpr.getSimpleName()));
                        }
                        continue;
                    }
                    throw new BusinessException("系统没有解析到你值，请联系管理员！" + sqlExpr.getParent());
                }
                listCoulmnValue.add(objectList);
                mapCoulmnValue.put(tableName, listCoulmnValue);
            }
            // 第一行为字段名称的集合
            for (Map.Entry<String, List<Object>> entry : mapCoulmnName.entrySet()) {
                if (!mapCoulmnValue.containsKey(entry.getKey())) {
                    continue;
                }
                List<List<Object>> listCoulmnValue = mapCoulmnValue.get(entry.getKey());
                listCoulmnValue.add(0, entry.getValue());
            }
            for (Map.Entry<String, List<List<Object>>> entry : mapCoulmnValue.entrySet()) {
                if (sqlVOMap.containsKey(ReportWorldEnum.RW_DB_SUFFIX.getCode() + tableName)) {
                    SqlScriptVO sqlScriptVO = sqlVOMap.get(ReportWorldEnum.RW_DB_SUFFIX.getCode() + tableName);
                    Database database = sqlScriptVO.getDatabase();
                    msgInfo.append(this.insertBaseDataBySqlScript(sqlScript, entry.getValue(), database, connection, mapInfo, mapInfoDemandBugInfo, sqlVOMap));
                } else {
                    QueryWrapper<Database> wrapper = new QueryWrapper();
                    wrapper.eq("CODE", ReportWorldEnum.RW_DB_SUFFIX.getCode() + tableName);
                    Database database = databaseMapper.selectOne(wrapper);
                    if (null == database) {
                        throw new BusinessException(entry.getKey() + "插入的数据不是基础数据，请检查！");
                    }
                    if (null != database.getDataBaseType() && 1 == database.getDataBaseType() && StringUtils.isEmpty(sqlScript.getDataBaseType())) { // 数据 要区分数据库类型 主要是插入SQL 语句的表 像结果集，ETL的部分表
                        throw new BusinessException(entry.getKey() + "该表数据需要区分数据库类型，请检查！");
                    }
                    msgInfo.append(this.insertBaseDataBySqlScript(sqlScript, entry.getValue(), database, connection, mapInfo, mapInfoDemandBugInfo, sqlVOMap));
                }
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
            throw new BusinessException("解析插入语句出错！" + ex.getMessage());
        }
    }

    /**
     * 解析语句的方法系统是否支持，和格式是否正确（新增和修改）
     *
     * @param sqlExpr
     */
    private String checkSQLMethodInvokeExpr(SQLExpr sqlExpr) {
        SQLMethodInvokeExpr invokeExpr = (SQLMethodInvokeExpr) sqlExpr;
        if (StringUtils.isNull(invokeExpr)) {
            throw new BusinessException("系统解析函数为空！" + invokeExpr.toString());
        }
        if (StringUtils.oneOf(invokeExpr.toString(), ORACLE_FUNCTION)) {
            throw new BusinessException("请不要使用ORACLE特殊函数！" + invokeExpr.toString());
        }
        if (StringUtils.oneCase(invokeExpr.toString(), "sys_guid(),SYS_GUID()")) {
            throw new BusinessException("新增脚本中不能使用sys_guid函数，请给出具体的值信息！");
        } else if (invokeExpr.getArguments().size() > 0 && StringUtils.oneCase(invokeExpr.getMethodName(), "to_date,TO_DATE")) {
            SQLCharExpr sqlCharExpr = (SQLCharExpr) invokeExpr.getArguments().get(0); // 对应的值
            SQLCharExpr sqlCharExpr2 = (SQLCharExpr) invokeExpr.getArguments().get(1); // 格式类型
            if (StringUtils.isNull(sqlCharExpr) || StringUtils.isNull(sqlCharExpr2) || StringUtils.isEmpty(sqlCharExpr2.getText())) {
                throw new BusinessException(invokeExpr.toString() + "函数中没有获取到值或者格式信息，请检查！");
            }
            if (!Pattern.matches(YssRegularEnum.DATE_TIME_REGULAR.getCode(), sqlCharExpr.getText())
                    && !(Pattern.matches(YssRegularEnum.DATE_REGULAR.getCode(), sqlCharExpr.getText()))) {
                throw new BusinessException(invokeExpr.toString() + "时间格式【" + sqlCharExpr + "】" +
                        "系统只支持【yyyy-MM-dd,或者yyyy-MM-dd HH:mm:ss】格式，请检查！");
            }
            if ((Pattern.matches(YssRegularEnum.DATE_TIME_REGULAR.getCode(), sqlCharExpr.getText()) && sqlCharExpr2.getText().equals(YssRegularEnum.DATE_TIME_REGULAR.getDesc()))
                    || ((Pattern.matches(YssRegularEnum.DATE_REGULAR.getCode(), sqlCharExpr.getText()) && sqlCharExpr2.getText().equals(YssRegularEnum.DATE_REGULAR.getDesc())))) {
                return sqlCharExpr.getText();
            } else {
                throw new BusinessException(invokeExpr.toString() + "时间格式【" + sqlCharExpr + "】和你的类型【" + sqlCharExpr2 + "】不一致，请检查（注意日期格式的大小写，如需要毫秒请用TIM）！");
            }
        } else {
            throw new BusinessException("系统不支持该方法的新增或者修改，请不要使用特殊函数！" + invokeExpr.toString());
        }
    }

    /**
     * 文件数据生成对应的insert语句
     *
     * @param listData
     * @param database
     * @param connection
     * @param sqlScript  sql脚本信息
     * @throws Exception
     */
    private String insertBaseDataBySqlScript(SqlScript sqlScript, List<List<Object>> listData, Database database, Connection connection,
                                             Map<String, String> mapInfo, Map<String, String> mapInfoDemandBugInfo, Map<String, SqlScriptVO> sqlVOMap) throws Exception {
        ResultSet rs = null;
        StringBuffer msgInfo = new StringBuffer();
        try {
            String code = database.getCode();
            this.getSqlScriptVO(listData, database, connection, sqlVOMap, code, sqlScript);
            SqlScriptVO sqlScriptVO = sqlVOMap.get(code);
            // 存放字段值和数据字段类型
            for (int i = 1; i < listData.size(); i++) {
                List<Object> objectList = listData.get(i);
                if (CollectionUtils.isEmpty(objectList)) {
                    continue;
                }
                List<Object> listInsert = new ArrayList<>();
                List<Object> listSelect = new ArrayList<>();
                // 数据拼接成Sql，同时校验数据
                StringBuffer buffer = new StringBuffer();
                for (int k = 0; k < objectList.size(); k++) {
                    Object obj = objectList.get(k);
                    //  原始的主键字段不能为空
                    if (StringUtils.isNotEmpty(sqlScriptVO.getDatabaseDispose())) {
                        for (Integer numReal : sqlScriptVO.getKeyNumReal()) {
                            if (k == numReal && (null == obj || StringUtils.isBlank(obj.toString()))) {
                                throw new BusinessException("表" + code.replace(ReportWorldEnum.RW_DB_SUFFIX.getCode(), "") + "主键字段值" + "【" + sqlScriptVO.getDataTypeCloumName().get(numReal) + "不能为空！");
                            }
                        }
                    }
                    listInsert.add(obj);
                    for (Integer number : sqlScriptVO.getOnlyName()) {
                        if (k == number) {
                            listSelect.add(obj);
                        }
                    }
                    if (StringUtils.isEmpty(sqlScriptVO.getListRegular())) {
                        continue;
                    }
                    for (DatabaseDispose dispose : sqlScriptVO.getListRegular()) {
                        if (StringUtils.isEmpty(dispose.getProp())) {
                            continue;
                        }
                        if (dispose.getProp().equals(sqlScriptVO.getDataTypeCloumName().get(k))) {
                            if (!Pattern.matches(dispose.getRegular(), obj.toString())) {
                                buffer.append("\r\n").append("=== 字段【" + dispose.getProp() + "】").append(dispose.getRegularMsg());
                            }
                        }
                    }
                }
                if (StringUtils.isNotEmpty(buffer.toString())) {
                    throw new BusinessException(buffer.append("\r\n").toString());
                }
                // 判断插入的数据业务主键是不是存在
                StringBuffer keyValue = new StringBuffer();
                StringBuffer keyPrimaryName = new StringBuffer();
                for (Integer integer : sqlScriptVO.getOnlyName()) {
                    keyValue.append(listInsert.get(integer)).append(",");
                    keyPrimaryName.append(sqlScriptVO.getDataTypeCloumName().get(integer)).append(",");
                }
                if (StringUtils.isNotEmpty(listSelect)) {
                    for (int m = 0; m < listSelect.size(); m++) {
                        JdbcUtil.addPreparedStatement(m, m, sqlScriptVO.getDataTypeName().get(sqlScriptVO.getOnlyName().get(m)), listSelect, sqlScriptVO.getPStemtSelect(), true);
                    }
                    rs = sqlScriptVO.getPStemtSelect().executeQuery();
                    if (rs.next()) {
                        // 修改的时候文件名不修改，重复审核导致原来数据会被删除
                        listInsert.add(YssStatusEnum.NORMAL.getCode()); // 状态
                        listInsert.add(rs.getString("RW_DB_FILE_NAME"));
                        listInsert.add(sqlScript.getVersion());
                        listInsert.add(DateUtils.dateToStrByFormat(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS));
                        listInsert.add(sqlScript.getCreateBy());
                        if (null != database.getDataBaseType() && 1 == database.getDataBaseType()) { // 需要区分数据库类型
                            listInsert.add(sqlScript.getDataBaseType());
                        }
                        int number = 0;
                        for (int m = 0; m < listInsert.size(); m++) { //更新成最新的，包括真实的主键字段
                            JdbcUtil.addPreparedStatement(number, m, sqlScriptVO.getDataTypeName().get(m), listInsert, sqlScriptVO.getPStemtUpdate());
                            number++;
                        }
                        // 条件开始的
                        for (int m = 0; m < listSelect.size(); m++) {
                            JdbcUtil.addPreparedStatement(number + m, m, sqlScriptVO.getDataTypeName().get(sqlScriptVO.getOnlyName().get(m)), listSelect, sqlScriptVO.getPStemtUpdate(), true);
                        }
                        sqlScriptVO.getPStemtUpdate().addBatch();
                        // 修改数据的时候存修改前的主键值，存在 所属模块，所属客户，所属报表，需求信息
                        mapInfo.put(rs.getString("RW_DB_ID"), code.toUpperCase());
                        mapInfoDemandBugInfo.put(rs.getString("RW_DB_ID"), code.toUpperCase());
                        msgInfo.append("***表" + code.replace(ReportWorldEnum.RW_DB_SUFFIX.getCode(), "")).
                                append("【业务主键" + keyPrimaryName).append("】对应值【").append(keyValue + "】系统已经存在该条数据，该数据会被更新，请核对数据！】");
                        // 对比数据是否存在差异
                        this.compareData(msgInfo, sqlScriptVO, listInsert, rs);
                        continue;
                    }
                    rs.close();
                }
                // 循环技术主键数据
                StringBuffer keyPkName = new StringBuffer();
                StringBuffer keyPkValue = new StringBuffer();
                List<String> dataTypeNamePk = new ArrayList<>();
                List<Object> listPk = new ArrayList<>();
                for (Integer numReal : sqlScriptVO.getKeyNumReal()) {
                    dataTypeNamePk.add(sqlScriptVO.getDataTypeName().get(numReal));
                    listPk.add(listInsert.get(numReal));
                    keyPkValue.append(listInsert.get(numReal)).append(",");
                    keyPkName.append(sqlScriptVO.getDataTypeCloumName().get(numReal)).append(",");
                }
                //  校验业务主键不一样，当时主键一致的情况，区分客户
                if (StringUtils.isNotNull(sqlScriptVO.getDatabaseDispose()) && StringUtils.isNotEmpty(sqlScriptVO.getDatabaseDispose())) {
                    for (int m = 0; m < listPk.size(); m++) {
                        JdbcUtil.addPreparedStatement(0, m, dataTypeNamePk.get(m), listPk, sqlScriptVO.getPStemtSelectPrimaryKey());
                    }
                    rs = sqlScriptVO.getPStemtSelectPrimaryKey().executeQuery();
                    if (rs.next()) {
                        msgInfo.append("***表" + code.replace(ReportWorldEnum.RW_DB_SUFFIX.getCode(), "")).
                                append("【技术主键" + keyPkName).append("】对应值【").append(keyPkValue + "】数据已经存在，请核对数据！】***").append("\r\n");
                        throw new BusinessException(msgInfo.toString());
                    }
                    rs.close();
                }
                // 添加文件名称和版本号
                listInsert.add(YssStatusEnum.NORMAL.getCode()); // 状态
                listInsert.add(sqlScript.getId());
                listInsert.add(sqlScript.getVersion());
                listInsert.add(DateUtils.dateToStrByFormat(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS));
                listInsert.add(sqlScript.getCreateBy());
                if (null != database.getDataBaseType() && 1 == database.getDataBaseType()) { // 需要区分数据库类型
                    listInsert.add(sqlScript.getDataBaseType());
                }
                if (sqlScriptVO.getDataMapPk().containsKey(keyPkValue.toString())) {
                    msgInfo.append("***表" + code.replace(ReportWorldEnum.RW_DB_SUFFIX.getCode(), "")).
                            append("【技术主键" + keyPkName).append("】对应值【").append(keyPkValue + "】存在重复数据，请核对数据！】***").append("\r\n");
                    throw new BusinessException(msgInfo.toString());
                }
                sqlScriptVO.getDataMapPk().put(keyPkValue.toString(), keyPkValue.toString());
                if (sqlScriptVO.getDataMapPrimaryKey().containsKey(keyValue.toString())) {
                    msgInfo.append("***表" + code.replace(ReportWorldEnum.RW_DB_SUFFIX.getCode(), "")).
                            append("【业务主键" + keyPrimaryName).append("】对应值【").append(keyValue + "】存在重复数据，请核对数据！】***").append("\r\n");
                    throw new BusinessException(msgInfo.toString());
                }
                sqlScriptVO.getDataMapPrimaryKey().put(keyValue.toString(), keyValue.toString());
                // 插入的数据第一个放的主键
                String keyValueId = IdUtils.fastSimpleUUID();
                listInsert.add(keyValueId);
                sqlScriptVO.getDataTypeName().add("VARCHAR"); //新增的最后一个字段是系统限定的主键字段
                for (int m = 0; m < listInsert.size(); m++) {
                    JdbcUtil.addPreparedStatement(m, m, sqlScriptVO.getDataTypeName().get(m), listInsert, sqlScriptVO.getPStemtInsert());
                }
                sqlScriptVO.getPStemtInsert().addBatch();
                // 新增的数据 所属模块，所属客户，所属报表，需求信息
                mapInfo.put(keyValueId, code.toUpperCase());
                mapInfoDemandBugInfo.put(keyValueId, code.toUpperCase());
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
            throw new BusinessException(database.getCode().replace(ReportWorldEnum.RW_DB_SUFFIX.getCode(), "") + "插入数据信息出错\r\n" + ex.getMessage());
        } finally {
            JdbcUtil.close(rs);
           /* JdbcUtil.close(pStemtSelectPrimaryKey);
            JdbcUtil.close(pStemtSelect);
            JdbcUtil.close(pStemtUpdate);
            JdbcUtil.close(pStemtInsert);*/
        }
        return msgInfo.toString();
    }

    /**
     * 获取没一个类型的数据信息
     *
     * @param listData
     * @param database
     * @param connection
     * @param sqlVOMap
     * @param code
     * @throws Exception
     */
    private void getSqlScriptVO(List<List<Object>> listData, Database database, Connection connection,
                                Map<String, SqlScriptVO> sqlVOMap, String code, SqlScript sqlScript) throws Exception {
        if (!sqlVOMap.containsKey(code)) {
            SqlScriptVO sqlScriptVO = new SqlScriptVO();
            PreparedStatement pStemtInsert = null;
            PreparedStatement pStemtUpdate = null;
            PreparedStatement pStemtSelect = null;
            PreparedStatement pStemtSelectPrimaryKey = null;
            // 读取数据库的字段类型
            Map<String, String> columnMap = JdbcUtil.getTableColumnNames("SELECT * FROM " + code + sqlScript.getVersionSuffix(), connection);
            List<Object> objects = listData.get(0);
            StringJoiner bufferFieldInsert = new StringJoiner(",");
            StringJoiner bufferFieldOnly = new StringJoiner(" ");
            StringJoiner bufferFieldValueUpdate = new StringJoiner(",");
            StringJoiner bufferFieldValueInsert = new StringJoiner(",");
            List<String> dataTypeName = new ArrayList<>();
            List<String> dataTypeCloumName = new ArrayList<>();
            // 业务主键字段
            List<Integer> onlyName = new ArrayList<>();
            QueryWrapper<DatabaseDispose> wrapper = new QueryWrapper<>();
            wrapper.eq("TABLE_NAME", code);
            wrapper.eq("IS_BUSINESS_PRIMARY", YssYseNoEnum.YES.getCode());
            List<DatabaseDispose> listBusinessPrimary = databaseDisposeService.list(wrapper);
            // 原来表的主键信息
            QueryWrapper<DatabaseDispose> wrapperDispose = new QueryWrapper<>();
            wrapperDispose.eq("TABLE_NAME", code);
            wrapperDispose.eq("IS_PRIMARY", YssYseNoEnum.YES.getCode());
            wrapperDispose.orderByAsc("ORDER_NUM");
            List<DatabaseDispose> databaseDispose = databaseDisposeService.list(wrapperDispose);
            // 业务主键重复的是否比较的字段
            QueryWrapper<DatabaseDispose> wrapperCompare = new QueryWrapper<>();
            wrapperCompare.eq("TABLE_NAME", code);
            wrapperCompare.eq("IS_COMPARE", YssYseNoEnum.YES.getCode());
            wrapperCompare.orderByAsc("ORDER_NUM");
            List<DatabaseDispose> listCompare = databaseDisposeService.list(wrapperCompare);
            // 配置了正则表达式的字段
            QueryWrapper<DatabaseDispose> wrapperRegular = new QueryWrapper<>();
            wrapperRegular.eq("TABLE_NAME", code);
            wrapperRegular.isNotNull("REGULAR");
            List<DatabaseDispose> listRegular = databaseDisposeService.list(wrapperRegular);
            List<Integer> keyNumReal = new ArrayList<>();
            for (int num = 0; num < objects.size(); num++) {
                Object object = objects.get(num);
                if (null == object || StringUtils.isEmpty(object.toString())) {
                    continue;
                }
                // 取除字段里的关键字带了符号的处理
                String columnName = object.toString().replaceAll("'", "").replaceAll("`", "").toUpperCase();
                if (StringUtils.isNotEmpty(databaseDispose)) {
                    for (DatabaseDispose dispose : databaseDispose) {
                        if (StringUtils.isNull(dispose) || !dispose.getProp().toUpperCase().equals(columnName)) {
                            continue;
                        }
                        keyNumReal.add(num);
                    }
                }
                if (columnMap.containsKey(columnName)) {
                    dataTypeName.add(columnMap.get(columnName));
                    dataTypeCloumName.add(columnName);
                } else {
                    throw new BusinessException("表结构信息【" + code.replace(ReportWorldEnum.RW_DB_SUFFIX.getCode(), "") + "】中未找到字段【" + columnName + "】信息，请检查！");
                }
                // 判断唯一数据的字段
                if (StringUtils.isNotEmpty(listBusinessPrimary)) {
                    for (DatabaseDispose dispose : listBusinessPrimary) {
                        if (StringUtils.isNull(dispose) || StringUtils.isEmpty(dispose.getProp())) {
                            continue;
                        }
                        if (!dispose.getProp().equals(columnName)) {
                            continue;
                        }
                        onlyName.add(num);
                        // 带了 IFNULL 走不了索引
                        if (null == dispose.getRequired() || 2 == dispose.getRequired()) {
                            bufferFieldOnly.add(" AND IFNULL(`" + dispose.getProp() + "`,'') = ? ");
                        } else {
                            bufferFieldOnly.add(" AND `" + dispose.getProp() + "` = ? ");
                        }
                    }
                }
                // MYSQL关键字处理
                bufferFieldInsert.add("`" + columnName + "`");
                bufferFieldValueUpdate.add("`" + columnName + "`= ?");
                bufferFieldValueInsert.add("?");
            }
            //查询语句判断是否已经存在
            StringBuffer selectSqlOnly = new StringBuffer();
            selectSqlOnly.append("SELECT * FROM " + code + sqlScript.getVersionSuffix()).append(" WHERE 1=1");
            if (null != database.getDataBaseType() && 1 == database.getDataBaseType()) { // 需要区分数据库类型
                bufferFieldOnly.add(" AND RW_DB_DATABASE_TYPE='" + sqlScript.getDataBaseType() + "'");
            }
            String sqlBuffer = this.getSqlBuffer(sqlScript, code);
            selectSqlOnly.append(sqlBuffer);
            selectSqlOnly.append(bufferFieldOnly);
            // 判断数据是不是已经存在
            pStemtSelect = connection.prepareStatement(selectSqlOnly.toString());
            // 数据不存在insert语句
            StringBuffer insertSql = new StringBuffer();
            insertSql.append("INSERT INTO " + code + sqlScript.getVersionSuffix()).append("(");
            // 添加文件名称和版本号
            if (null != database.getDataBaseType() && 1 == database.getDataBaseType()) { // 需要区分数据库类型
                bufferFieldInsert.add("RW_DB_STATUS,RW_DB_FILE_NAME,RW_DB_VERSION,RW_DB_ADD_TIME,RW_DB_ADD_USER,RW_DB_DATABASE_TYPE,RW_DB_ID");
                bufferFieldValueInsert.add("?");
            } else {
                bufferFieldInsert.add("RW_DB_STATUS,RW_DB_FILE_NAME,RW_DB_VERSION,RW_DB_ADD_TIME,RW_DB_ADD_USER,RW_DB_ID");
            }
            insertSql.append(bufferFieldInsert).append(") VALUES (");
            bufferFieldValueInsert.add("?,?,?,?,?,?");
            insertSql.append(bufferFieldValueInsert).append(")");
            pStemtInsert = connection.prepareStatement(insertSql.toString());
            // 数据存在修改语句
            StringBuffer updateSql = new StringBuffer();
            updateSql.append("UPDATE " + code + sqlScript.getVersionSuffix() + " SET ");
            // 添加文件名称和版本号
            if (null != database.getDataBaseType() && 1 == database.getDataBaseType()) { // 需要区分数据库类型
                bufferFieldValueUpdate.add(" RW_DB_STATUS=?,RW_DB_FILE_NAME=?,RW_DB_VERSION = ?,RW_DB_EDIT_TIME=?,RW_DB_EDIT_USER=?,RW_DB_DATABASE_TYPE = ?");
            } else {
                bufferFieldValueUpdate.add(" RW_DB_STATUS=?,RW_DB_FILE_NAME=?,RW_DB_VERSION = ?,RW_DB_EDIT_TIME=?,RW_DB_EDIT_USER=?");
            }
            updateSql.append(bufferFieldValueUpdate).append(" WHERE 1=1 ").append(sqlBuffer).append(bufferFieldOnly);
            pStemtUpdate = connection.prepareStatement(updateSql.toString());
            // 添加固定的类型 状态，文件名称，版本号，添加人，修改人(插入的时候) 添加时间，修改时间（修改的时候）
            String[] arrDataTypeName = new String[]{"DECIMAL", "VARCHAR", "VARCHAR", "DATETIME", "VARCHAR"};
            if (null != database.getDataBaseType() && 1 == database.getDataBaseType()) { // 需要区分数据库类型
                arrDataTypeName = new String[]{"DECIMAL", "VARCHAR", "VARCHAR", "DATETIME", "VARCHAR", "VARCHAR"};
            }
            for (String typeName : arrDataTypeName) {
                dataTypeName.add(typeName);
            }
            if (StringUtils.isEmpty(databaseDispose) || StringUtils.isEmpty(keyNumReal)) {
                throw new BusinessException(code + "没有获取到配置的主键信息");
            }
            StringBuffer sql = new StringBuffer("SELECT 1 FROM " + code + sqlScript.getVersionSuffix() + " WHERE RW_DB_STATUS=1 AND ");
            if (null != database.getDataBaseType() && 1 == database.getDataBaseType()) { // 需要区分数据库类型的数据，技术主键可以重复
                sql.append(" RW_DB_DATABASE_TYPE='" + sqlScript.getDataBaseType() + "' AND ");
            }
            StringJoiner bufferPkColumn = new StringJoiner(","); // 技术主键
            for (DatabaseDispose dispose : databaseDispose) {
                bufferPkColumn.add(dispose.getProp() + "=?");
            }
            sql.append(bufferPkColumn);
            sql.append(sqlBuffer);
            pStemtSelectPrimaryKey = connection.prepareStatement(sql.toString());
            sqlScriptVO.setPStemtSelectPrimaryKey(pStemtSelectPrimaryKey);
            sqlScriptVO.setPStemtInsert(pStemtInsert);
            sqlScriptVO.setPStemtSelect(pStemtSelect);
            sqlScriptVO.setPStemtUpdate(pStemtUpdate);
            sqlScriptVO.setDatabaseDispose(databaseDispose);
            sqlScriptVO.setListBusinessPrimary(listBusinessPrimary);
            sqlScriptVO.setListCompare(listCompare);
            sqlScriptVO.setListRegular(listRegular);
            sqlScriptVO.setDataTypeName(dataTypeName);
            sqlScriptVO.setDataTypeCloumName(dataTypeCloumName);
            sqlScriptVO.setKeyNumReal(keyNumReal);
            sqlScriptVO.setOnlyName(onlyName);
            sqlScriptVO.setDatabase(database);
            sqlScriptVO.setDataMapPk(new HashMap<>());
            sqlScriptVO.setDataMapPrimaryKey(new HashMap<>());
            sqlVOMap.put(code, sqlScriptVO);
        }
    }

    // 是否同时存在的情况，新增，修改，删除的时候拼接上对应的客户，报表和模块
    private String getSqlBuffer(SqlScript sqlScript, String code) {
        if (StringUtils.isEmpty(code) || StringUtils.isNull(sqlScript)) {
            return "";
        }
        // 是否同时存在
        StringBuffer sqlBuffer = new StringBuffer();
        if (null == sqlScript.getCoverPrimaryKey() || 1 != sqlScript.getCoverPrimaryKey()) {
            return "";
        }
        if (StringUtils.isNotEmpty(sqlScript.getModularId())) {
            sqlBuffer.append(" AND RW_DB_ID IN(SELECT DATA_ID FROM REPORT_WORLD_DATA_MODULAR WHERE DATA_CODE ='")
                    .append(code.toUpperCase()).append("' AND MODULAR_ID='").append(sqlScript.getModularId()).append("')");
        }
        if (StringUtils.isNotEmpty(sqlScript.getCustomerId())) {
            sqlBuffer.append(" AND RW_DB_ID IN(SELECT DATA_ID FROM REPORT_WORLD_DATA_CUSTOMER WHERE DATA_CODE ='")
                    .append(code.toUpperCase()).append("' AND CUSTOMER_ID='").append(sqlScript.getCustomerId()).append("')");
        }
        if (StringUtils.isNotEmpty(sqlScript.getReportId())) {
            sqlBuffer.append(" AND RW_DB_ID IN(SELECT DATA_ID FROM REPORT_WORLD_DATA_REPORT WHERE DATA_CODE ='")
                    .append(code.toUpperCase()).append("' AND REPORT_ID='").append(sqlScript.getReportId()).append("')");
        }

        return sqlBuffer.toString();
    }

    /**
     * 执行修改语句
     *
     * @param stmt
     * @param sqlScript
     * @param mapInfo
     * @return
     * @throws Exception
     */
    private void sqlUpdateStatement(SQLStatement stmt, SqlScript
            sqlScript, Map<String, String> mapInfo, Connection connection,
                                    Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo,
                                    Map<String, SqlScriptVO> sqlVOMap) throws Exception {
        this.sqlUpdateStatement(stmt, sqlScript, mapInfo, connection, mapInfoDemandBugInfo, null, msgInfo, sqlVOMap);
    }

    /**
     * 执行修改语句
     *
     * @param stmt
     * @param sqlScript
     * @param mapInfo
     * @return
     * @throws Exception
     */
    private void sqlUpdateStatement(SQLStatement stmt, SqlScript
            sqlScript, Map<String, String> mapInfo, Connection connection, Map<String, String> mapInfoDemandBugInfo,
                                    Map<String, Object> mapDeclare, StringBuffer msgInfo, Map<String, SqlScriptVO> sqlVOMap) throws Exception {
        PreparedStatement pStemtUpdate = null;
        PreparedStatement pStemtSelect = null;
        ResultSet rs = null;
        try {
            SQLUpdateStatement updateStatement = (SQLUpdateStatement) stmt;
            SQLExprTableSource sqlTableSource = (SQLExprTableSource) updateStatement.getTableSource();
            this.checkTableAlias(sqlTableSource);
            String tableName = sqlTableSource.getName().getSimpleName();
            if (StringUtils.isBlank(tableName)) {
                throw new BusinessException("没有获取到修改句里的表名信息！" + sqlTableSource.getParent());
            }
            // 判断是否配置的基础数据
            String code = ReportWorldEnum.RW_DB_SUFFIX.getCode() + tableName.toUpperCase();
            QueryWrapper<Database> wrapper = new QueryWrapper();
            wrapper.eq("CODE", code);
            Database database = databaseMapper.selectOne(wrapper);
            if (null == database) {
                throw new BusinessException("修改的数据不是基础数据，请检查！" + sqlTableSource.getParent());
            }
            if (null != database.getDataBaseType() && 1 == database.getDataBaseType() && StringUtils.isBlank(sqlScript.getDataBaseType())) {  // 配置要区分数据库类型的数据
                throw new BusinessException("修改的数据需要区分数据库类型，请选择数据库类型！" + sqlTableSource.getParent());
            }
            List<SQLUpdateSetItem> list = updateStatement.getItems();
            if (CollectionUtils.isEmpty(list)) {
                throw new BusinessException("没有获取到修改数据的SET的值，请检查！" + sqlTableSource.getParent());
            }
            StringBuffer updateSql = new StringBuffer();
            updateSql.append("UPDATE " + code + sqlScript.getVersionSuffix() + " SET RW_DB_STATUS = ? , RW_DB_EDIT_TIME= ?, RW_DB_EDIT_USER=?, ");
            StringJoiner bufferUpdate = new StringJoiner(",");
            List<Object> valueList = new ArrayList<>();
            SqlScriptVO scriptVO = null;
            if (sqlVOMap.containsKey(code)) {
                scriptVO = sqlVOMap.get(code);
            } else {
                scriptVO = new SqlScriptVO();
                // 配置了正则表达式的字段
                QueryWrapper<DatabaseDispose> wrapperRegular = new QueryWrapper<>();
                wrapperRegular.eq("TABLE_NAME", code);
                wrapperRegular.isNotNull("REGULAR");
                List<DatabaseDispose> listRegular = databaseDisposeService.list(wrapperRegular);
                scriptVO.setListRegular(listRegular);
                sqlVOMap.put(code, scriptVO);
            }
            for (SQLUpdateSetItem item : list) {
                SQLExpr expr = item.getColumn();
                if (expr instanceof SQLPropertyExpr) {
                    throw new BusinessException("修改语句中不用别名，请检查！" + sqlTableSource.getParent());
                }
                SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) item.getColumn();
                String columnName = identifierExpr.getName(); // 修改的字段
                if (StringUtils.isBlank(columnName)) {
                    throw new BusinessException("没有获取到修改字段的信息，请检查！" + sqlTableSource.getParent());
                }
                columnName = columnName.replaceAll("'", "").replaceAll("`", "").toUpperCase();
                bufferUpdate.add("`" + columnName + "`=?");
                SQLExpr sqlExpr = item.getValue();
                if (sqlExpr instanceof SQLNullExpr) { //字符类型
                    valueList.add(null);
                } else if (sqlExpr instanceof SQLCharExpr) { //字符类型
                    SQLCharExpr sqlCharExpr = (SQLCharExpr) sqlExpr;
                    valueList.add(sqlCharExpr.getText());
                } else if (sqlExpr instanceof SQLIntegerExpr) { //字符类型
                    SQLIntegerExpr sqlIntegerExpr = (SQLIntegerExpr) sqlExpr;
                    if (null != sqlIntegerExpr) {
                        valueList.add(sqlIntegerExpr.getNumber());
                    }
                } else if (sqlExpr instanceof SQLMethodInvokeExpr) { // 方法类型 如 sys_guid()
                    valueList.add(this.checkSQLMethodInvokeExpr(sqlExpr));
                } else if (sqlExpr instanceof OracleSysdateExpr) { // ORACLE 的 SYSDATE默认值
                    valueList.add(DateUtils.dateToStrByFormat(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS));
                } else if (sqlExpr instanceof SQLNumberExpr) { //字符类型
                    SQLNumberExpr sqlNumberExpr = (SQLNumberExpr) sqlExpr;
                    valueList.add(sqlNumberExpr.getNumber());
                } else if (sqlExpr instanceof SQLTimestampExpr) {
                    SQLTimestampExpr invokeExpr = (SQLTimestampExpr) sqlExpr;
                    valueList.add(invokeExpr.getLiteral());
                } else if (sqlExpr instanceof SQLBinaryOpExpr) { // 拼接的类型  例如 '请输入' || '管理人统一社会信用代码'
                    SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) sqlExpr;
                    valueList.add(binaryOpExpr.getLeft() + "||" + binaryOpExpr.getRight());
                } else if (sqlExpr instanceof SQLIdentifierExpr && !CollectionUtils.isEmpty(mapDeclare)) {
                    SQLIdentifierExpr invokeExpr = (SQLIdentifierExpr) sqlExpr;
                    if (null != invokeExpr && mapDeclare.containsKey(invokeExpr.getSimpleName())) {
                        valueList.add(mapDeclare.get(invokeExpr.getSimpleName()));
                    }
                } else if (sqlExpr instanceof SQLQueryExpr) { // set的值是一个查询语句
                    throw new BusinessException("修改语句请给出SET的具体值，系统不支持SET的内容是一个SELECT的语句！" + sqlExpr.getParent());
                } else {
                    throw new BusinessException("系统没有解析到你值，请联系管理员！" + sqlExpr.getParent());
                }
                if (StringUtils.isNotEmpty(scriptVO.getListRegular()) && StringUtils.isNotNull(valueList)
                        && StringUtils.isNotNull(valueList.get(valueList.size() - 1))) {
                    for (DatabaseDispose dispose : scriptVO.getListRegular()) {
                        if (StringUtils.isEmpty(dispose.getProp()) || !columnName.toUpperCase().equals(dispose.getProp())) {
                            continue;
                        }
                        if (!Pattern.matches(dispose.getRegular(), valueList.get(valueList.size() - 1).toString())) {
                            throw new BusinessException("SQL脚本【" + stmt + "】===修改后字段【" + dispose.getProp() + "】" + dispose.getRegularMsg());
                        }
                    }
                }
            }
            updateSql.append(bufferUpdate);
            StringBuffer sqlWhere = new StringBuffer();
            SQLExpr opExpr = updateStatement.getWhere();
            if (opExpr instanceof SQLBinaryOpExpr) {
                opExpr = updateStatement.getWhere();
                if (null != opExpr) { // where 条件
                    sqlWhere.append(opExpr);
                }
            }
            if (opExpr instanceof SQLInListExpr) { // where 条件是单独一个in的时候
                StringJoiner updateWhere = new StringJoiner(",");
                SQLInListExpr listExpr = (SQLInListExpr) opExpr;
                SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) listExpr.getExpr();
                sqlWhere.append(identifierExpr.getName()).append(" IN (");// 字段名
                List<SQLExpr> exprList = listExpr.getTargetList();
                for (SQLExpr sqlExpr : exprList) {
                    if (sqlExpr instanceof SQLCharExpr) {
                        SQLCharExpr charExpr = (SQLCharExpr) sqlExpr;
                        updateWhere.add("'" + charExpr.getValue() + "'");
                        continue;
                    }
                    if (sqlExpr instanceof SQLIntegerExpr) { //字符类型
                        SQLIntegerExpr sqlIntegerExpr = (SQLIntegerExpr) sqlExpr;
                        if (null != sqlIntegerExpr) {
                            updateWhere.add(sqlIntegerExpr.getNumber().toString());
                        }
                        continue;
                    }
                    throw new BusinessException("系统没有解析到你修改语句条件的值，请联系管理员！" + sqlExpr.getParent());
                }
                sqlWhere.append(updateWhere);
                sqlWhere.append(")");
            } else if (stmt instanceof OracleUpdateStatement) {
                OracleUpdateStatement updateStatement1 = (OracleUpdateStatement) stmt;
                if (updateStatement1.getWhere() instanceof SQLInSubQueryExpr) {
                    throw new BusinessException("修改的数据不要用子查询，请列除具体值或者按照某一列的值修改！" + stmt);
                }
            } else {
                throw new BusinessException("系统没有解析到你的修改语句，请联系管理员！" + stmt);
            }
            if (StringUtils.isNotBlank(sqlWhere.toString())) {
                updateSql.append(" WHERE RW_DB_STATUS=1 AND ").append(sqlWhere);
            }
            if (null != database.getDataBaseType() && 1 == database.getDataBaseType()) {  // 配置要区分数据库类型的数据
                if (StringUtils.isNotBlank(sqlWhere.toString())) {
                    sqlWhere.append(" AND RW_DB_DATABASE_TYPE='").append(sqlScript.getDataBaseType()).append("'");
                } else {
                    sqlWhere.append(" WHERE RW_DB_STATUS=1 RW_DB_DATABASE_TYPE='").append(sqlScript.getDataBaseType()).append("'");
                }
            }
            // 是否同时存在
            updateSql.append(this.getSqlBuffer(sqlScript, code));
            pStemtUpdate = connection.prepareStatement(updateSql.toString());
            pStemtUpdate.setInt(1, YssStatusEnum.NORMAL.getCode());
            pStemtUpdate.setTimestamp(2, new java.sql.Timestamp(new Date().getTime()));
            pStemtUpdate.setString(3, sqlScript.getCreateBy());
            for (int i = 0; i < valueList.size(); i++) {
                pStemtUpdate.setObject(4 + i, valueList.get(i));
            }
            // 查询修改的数据
            // 按照条件查询 对应数据的主键信息，添加修改记录
            StringBuffer selectSql = new StringBuffer();
            selectSql.append("SELECT RW_DB_ID FROM " + code + sqlScript.getVersionSuffix());
            if (StringUtils.isNotBlank(sqlWhere.toString())) {
                selectSql.append(" WHERE RW_DB_STATUS=1 AND ").append(sqlWhere);
            }
            // 是否同时存在
            selectSql.append(this.getSqlBuffer(sqlScript, code));
            pStemtSelect = connection.prepareStatement(selectSql.toString());
            rs = pStemtSelect.executeQuery();
            int count = 0;
            while (rs.next()) {
                mapInfoDemandBugInfo.put(rs.getString(1), code);
                mapInfo.put(rs.getString(1), code.toUpperCase());
                count++;
            }
            if (0 == count) {
                msgInfo.append("<font color='red'>***SQL脚本【" + stmt + "】").append("没有修改任何数据，请检查确认！***</font>").append("\r\n");
            }
            if (count > 0) { // 条件不是in ,删除了多条的提示
                msgInfo.append("</font>***SQL脚本【" + stmt + "】").append("会修改" + count + "条数据，请检查确认！***</font>").append("\r\n");
            }
            pStemtUpdate.execute();
        } finally {
            JdbcUtil.close(rs);
            JdbcUtil.close(pStemtSelect);
            JdbcUtil.close(pStemtUpdate);
        }
    }

    /**
     * 解析的表名里面是否包含了数据库名称
     *
     * @param sqlTableSource
     */
    private void checkTableAlias(SQLExprTableSource sqlTableSource) {
        if (sqlTableSource.getExpr() instanceof SQLPropertyExpr) {
            SQLPropertyExpr propertyExpr = (SQLPropertyExpr) sqlTableSource.getExpr();
            SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) propertyExpr.getOwner();
            if (StringUtils.isNotEmpty(identifierExpr.getSimpleName())) {
                throw new BusinessException("<font color='red'>***脚本信息中的表名包含了数据库名称，请检查！【" + identifierExpr.getSimpleName() + "】***</font>");
            }
        }
    }

    /**
     * 解析BLOB类型字段插入的
     *
     * @param stmt
     * @param sqlScript
     * @param mapInfo
     * @param mapInfoDemandBugInfo
     * @throws Exception
     */
    private void sqlBlockStatement(SQLStatement stmt, SqlScript sqlScript, Map<String, String> mapInfo,
                                   Connection connection, Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo) throws Exception {
        try {
            SQLBlockStatement statement = (SQLBlockStatement) stmt;
            List<SQLStatement> list = statement.getStatementList();
            if (CollectionUtils.isEmpty(list)) {
                throw new BusinessException("没有获取到插入语句信息，请检查！" + statement.getParent());
            }
            Map<String, Object> mapDeclare = new HashMap<>();
            Map<String, SqlScriptVO> sqlVOMapInsert = new HashMap<>();
            Map<String, SqlScriptVO> sqlVOMapUpdate = new HashMap<>();
            for (SQLStatement sqlStatement : list) {
                if (sqlStatement instanceof SQLSetStatement) { // 参数
                    List<SQLAssignItem> listItem = ((SQLSetStatement) sqlStatement).getItems();
                    for (SQLAssignItem sqlAssignItem : listItem) {
                        SQLIdentifierExpr expr = (SQLIdentifierExpr) sqlAssignItem.getTarget(); // 参数名称
                        String key = expr.getSimpleName();
                        if (StringUtils.isBlank(key)) {
                            throw new BusinessException("<font color='red'>***BLOB类型的插入没有解析出对应的变量信息，请检查！" + statement.getParent() + "***</font>");
                        }
                        SQLExpr sqlExpr = sqlAssignItem.getValue(); // 参数值
                        if (sqlExpr instanceof SQLCharExpr) {
                            SQLCharExpr invokeExpr = (SQLCharExpr) sqlExpr;
                            String value = invokeExpr.getText();
                            mapDeclare.put(key, value);
                        } else {
                            throw new BusinessException("<font color='red'>***BLOB类型的插入系统现在只支持字符类型的，请检查！" + statement.getParent() + "***</font>");
                        }

                    }
                    continue;
                }
                if (sqlStatement instanceof OracleInsertStatement) { // 插入语句
                    OracleInsertStatement sqlInsertStatement = (OracleInsertStatement) sqlStatement;
                    this.sqlInsertStatement(sqlInsertStatement, sqlScript, mapInfo, connection, mapInfoDemandBugInfo, msgInfo, mapDeclare, sqlVOMapInsert);
                    continue;
                }
                if (sqlStatement instanceof OracleUpdateStatement) { // 修改语句
                    OracleUpdateStatement sqlUpdateStatement = (OracleUpdateStatement) sqlStatement;
                    this.sqlUpdateStatement(sqlUpdateStatement, sqlScript, mapInfo, connection, mapInfoDemandBugInfo, mapDeclare, msgInfo, sqlVOMapUpdate);
                    continue;
                }
                for (Map.Entry<String, SqlScriptVO> entry : sqlVOMapInsert.entrySet()) {
                    SqlScriptVO vo = entry.getValue();
                    if (StringUtils.isNull(vo)) {
                        continue;
                    }
                    if (StringUtils.isNotNull(vo.getPStemtUpdate())) {
                        vo.getPStemtUpdate().executeBatch();
                        vo.getPStemtUpdate().close();
                    }
                    if (StringUtils.isNotNull(vo.getPStemtInsert())) {
                        vo.getPStemtInsert().executeBatch();
                        vo.getPStemtInsert().close();
                    }
                    if (StringUtils.isNotNull(vo.getPStemtSelect())) {
                        vo.getPStemtSelect().close();
                    }
                    if (StringUtils.isNotNull(vo.getPStemtSelectPrimaryKey())) {
                        vo.getPStemtSelectPrimaryKey().close();
                    }
                }
                throw new BusinessException("系统还不支持该类型的语句！" + statement.getParent());
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
            throw new BusinessException("解析大字段的插入语句出错！" + ex.getMessage());
        }
    }

    /**
     * 检查表和字段的规范
     *
     * @param sqlScript
     * @param mapInfoDemandBugInfo
     * @throws Exception
     */
    private void tableStandardCheckInfo(SqlScript sqlScript, Map<String, String> mapInfoDemandBugInfo, StringBuffer msgInfo) throws Exception {
        if (CollectionUtils.isEmpty(mapInfoDemandBugInfo)) {
            return;
        }
        try {
            YssResponse<String> response = remoteConfigService.getConfigByKey(YssConfigEnum.REPORTWORLD_TABLE_WARNING.getCode(), SecurityConstants.INNER);
            String tables = StringUtils.isEmpty(response.getData()) ? "" : response.getData();
            StringBuffer msg = new StringBuffer();
            for (Map.Entry<String, String> entry : mapInfoDemandBugInfo.entrySet()) {
                if (null == entry || StringUtils.isBlank(entry.getKey()) || StringUtils.isBlank(entry.getValue())) {
                    continue;
                }
                if (ReportWorldEnum.REPORT_TABLE_CODE.getCode().equals(entry.getValue())) {
                    QueryWrapper<Table> wrapper = new QueryWrapper<>();
                    wrapper.eq("ID", entry.getKey());
                    Table table = tableMapper.selectOne(wrapper);
                    if (null == table || StringUtils.isBlank(table.getId())) {
                        throw new BusinessException("检查表规范的时候，获取表信息失败！");
                    }
                    // 表和字段的规范
                    List<String> listModular = new ArrayList<>();
                    listModular.add(sqlScript.getModularId());
                    table.setStrModular(listModular);
                    List<String> listCustomer = new ArrayList<>();
                    listCustomer.add(sqlScript.getCustomerId());
                    table.setStrCustomer(listCustomer);
                    List<String> listReport = new ArrayList<>();
                    listReport.add(sqlScript.getReportId());
                    table.setStrReport(listReport);
                    try {
                        tableStandardCheckService.tableStandardCheckInfo(table, true);
                    } catch (Exception ex) {
                        msg.append(ex.getMessage()).append("\r\n");
                    }
                    //系统参数设置的数据量大的表调整，提示
                    if (StringUtils.isNotEmpty(tables) && StringUtils.oneCase(table.getName().toUpperCase(), tables.toUpperCase())) {
                        msgInfo.append("<font color='red'>***调整的表属于系统大数据量的表【" + table.getName() + "】，请联系脚本审核人员处理！***</font>").append("\r\n");
                    }
                } else if (ReportWorldEnum.REPORT_TABLE_DETAIL_CODE.getCode().equals(entry.getValue())) {
                    QueryWrapper<TableDetail> wrapper = new QueryWrapper<>();
                    wrapper.eq("ID", entry.getKey());
                    TableDetail tableDetail = tableDetailMapper.selectOne(wrapper);
                    if (null == tableDetail || StringUtils.isBlank(tableDetail.getId())) {
                        throw new BusinessException("检查表字段规范的时候，获取表字段信息失败！");
                    }
                    try {
                        tableDetailStandardCheckService.tableDetailStandardCheckInfo(tableDetail);
                    } catch (Exception ex) {
                        msg.append(ex.getMessage()).append("\r\n");
                    }
                }
            }
            if (StringUtils.isNotEmpty(msg)) {
                throw new BusinessException(msg.toString());
            }
        } catch (Exception ex) {
            throw new BusinessException(ex.getMessage());
        }
    }

    /**
     * 插入文件里的的所属模块，客户，报表
     *
     * @param sqlScript
     * @param mapInfo
     * @throws Exception
     */
    public void insertDataBaseSign(SqlScript sqlScript, Map<String, String> mapInfo) throws Exception {
        //  循环基础数据的对应模块，客户，需求bug
        for (Map.Entry<String, String> entry : mapInfo.entrySet()) {
            if (null == entry || StringUtils.isBlank(entry.getKey()) || StringUtils.isBlank(entry.getValue())) {
                continue;
            }
            // 更新数据标记
            if (1 == sqlScript.getDataMark()) {
                QueryWrapper<DataModular> modularQueryWrapper = new QueryWrapper<>();
                modularQueryWrapper.eq("DATA_ID", entry.getKey());
                modularQueryWrapper.eq("DATA_CODE", entry.getValue());
                dataModularMapper.delete(modularQueryWrapper);
                QueryWrapper<DataReport> reportQueryWrapper = new QueryWrapper<>();
                reportQueryWrapper.eq("DATA_ID", entry.getKey());
                reportQueryWrapper.eq("DATA_CODE", entry.getValue());
                dataReportMapper.delete(reportQueryWrapper);
                QueryWrapper<DataCustomer> customerQueryWrapper = new QueryWrapper<>();
                customerQueryWrapper.eq("DATA_ID", entry.getKey());
                customerQueryWrapper.eq("DATA_CODE", entry.getValue());
                dataCustomerMapper.delete(customerQueryWrapper);
            }
            if (StringUtils.isNotBlank(sqlScript.getModularId())) {
                // 先删除在插入数据
                if (2 == sqlScript.getDataMark()) {
                    QueryWrapper<DataModular> modularQueryWrapper = new QueryWrapper<>();
                    modularQueryWrapper.eq("DATA_ID", entry.getKey());
                    modularQueryWrapper.eq("MODULAR_ID", sqlScript.getModularId());
                    modularQueryWrapper.eq("DATA_CODE", entry.getValue());
                    dataModularMapper.delete(modularQueryWrapper);
                }
                DataModular modular = new DataModular();
                modular.setId(IdUtils.fastSimpleUUID());
                modular.setDataCode(entry.getValue());
                modular.setFileName(sqlScript.getId());
                modular.setDataId(entry.getKey());
                modular.setModularId(sqlScript.getModularId());
                dataModularMapper.insert(modular);
            }
            if (StringUtils.isNotBlank(sqlScript.getReportId())) {
                if (2 == sqlScript.getDataMark()) {
                    QueryWrapper<DataReport> reportQueryWrapper = new QueryWrapper<>();
                    reportQueryWrapper.eq("DATA_ID", entry.getKey());
                    reportQueryWrapper.eq("REPORT_ID", sqlScript.getReportId());
                    reportQueryWrapper.eq("DATA_CODE", entry.getValue());
                    dataReportMapper.delete(reportQueryWrapper);
                }
                DataReport report = new DataReport();
                report.setId(IdUtils.fastSimpleUUID());
                report.setDataCode(entry.getValue());
                report.setFileName(sqlScript.getId());
                report.setDataId(entry.getKey());
                report.setReportId(sqlScript.getReportId());
                dataReportMapper.insert(report);
            }
            if (StringUtils.isNotBlank(sqlScript.getCustomerId())) {
                if (2 == sqlScript.getDataMark()) {
                    QueryWrapper<DataCustomer> customerQueryWrapper = new QueryWrapper<>();
                    customerQueryWrapper.eq("DATA_ID", entry.getKey());
                    customerQueryWrapper.eq("CUSTOMER_ID", sqlScript.getCustomerId());
                    customerQueryWrapper.eq("DATA_CODE", entry.getValue());
                    dataCustomerMapper.delete(customerQueryWrapper);
                }
                DataCustomer customer = new DataCustomer();
                customer.setId(IdUtils.fastSimpleUUID());
                customer.setDataCode(entry.getValue());
                customer.setFileName(sqlScript.getId());
                customer.setDataId(entry.getKey());
                customer.setCustomerId(sqlScript.getCustomerId());
                dataCustomerMapper.insert(customer);
            }
        }
    }

    /**
     * 插入文件数据对应的需求BUG
     *
     * @param sqlScript
     * @param mapInfo
     * @param mapDemandBugInfo
     * @throws Exception
     */
    private void insertDataBasedataDemandBug(SqlScript sqlScript, Map<String, String> mapInfo, Map<String, String> mapDemandBugInfo) throws Exception {
        //  循环基础数据的对应模块，客户，需求bug
        for (Map.Entry<String, String> entry : mapInfo.entrySet()) {
            if (null == entry || StringUtils.isBlank(entry.getKey()) || StringUtils.isBlank(entry.getValue())) {
                continue;
            }
            // 修改记录信息
            if (StringUtils.isNotBlank(sqlScript.getDemandBugId())
                    && !CollectionUtils.isEmpty(mapDemandBugInfo)) {
                QueryWrapper<DataDemandBug> updateInfoQueryWrapper = new QueryWrapper<>();
                updateInfoQueryWrapper.eq("DATA_ID", entry.getKey());
                updateInfoQueryWrapper.eq("DEMAND_BUG_ID", sqlScript.getDemandBugId());
                updateInfoQueryWrapper.eq("DATA_CODE", entry.getValue());
                dataDemandBugMapper.delete(updateInfoQueryWrapper);
                DataDemandBug dataDemandBug = new DataDemandBug();
                dataDemandBug.setId(IdUtils.fastSimpleUUID());
                dataDemandBug.setDataCode(entry.getValue());
                dataDemandBug.setDemandBugId(sqlScript.getDemandBugId());
                dataDemandBug.setDataId(entry.getKey());
                dataDemandBug.setDataCode(entry.getValue());
                dataDemandBug.setFileName(sqlScript.getId());
                dataDemandBugMapper.insert(dataDemandBug);
            }
        }
    }

    /**
     * 基础数据的检查
     *
     * @param sqlScript
     * @param mapInfoDemandBugInfo
     * @throws Exception
     */
    public void dataBaseCheckInfo(Connection connection, SqlScript sqlScript, Map<String, String> mapInfoDemandBugInfo,
                                  StringBuffer msgInfo, String version) throws Exception {
        if (CollectionUtils.isEmpty(mapInfoDemandBugInfo)) {
            return;
        }
        PreparedStatement pStemtSelect = null;
        ResultSet rs = null;
        try {
            Map<String, String> map = new HashMap();
            for (Map.Entry<String, String> entry : mapInfoDemandBugInfo.entrySet()) {
                if (null == entry || StringUtils.isBlank(entry.getKey()) || StringUtils.isBlank(entry.getValue())) {
                    continue;
                }
                String code = ReportWorldEnum.getEnumDescByCode(entry.getValue());
                if (map.containsKey(entry.getValue()) || StringUtils.isEmpty(code)) {
                    continue;
                }
                DatabaseCheck databaseCheck = new DatabaseCheck();
                databaseCheck.setTableCode(code.toUpperCase());
                databaseCheck.setHisVersion(version);
                String msg = databaseCheckService.queryCheckDataBaseInfoAll(databaseCheck, connection);
                if (StringUtils.isNotEmpty(msg)) {
                    msgInfo.append(msg);
                }
                if (!databaseCheck.getCheckPass()) {
                    throw new BusinessException("");
                }
                map.put(entry.getValue(), entry.getValue());
            }
        } catch (Exception ex) {
            throw new BusinessException(ex.getMessage());
        } finally {
            JdbcUtil.close(rs);
            JdbcUtil.close(pStemtSelect);
        }
    }

    /**
     * 获取能还原的版本号集合，前台显示
     *
     * @return
     */
    public List<SysDictData> getReductionVersion(boolean maxVersion) {
        QueryWrapper<Description> descriptionQueryWrapper = new QueryWrapper<>();
        descriptionQueryWrapper.eq("NAME", ReportWorldDescriptionEnum.BACKUPVERSION.getCode());
        Description description = descriptionService.getOne(descriptionQueryWrapper);
        if (null == description || StringUtils.isBlank(description.getDescription())) {
            throw new BusinessException("没有获取到要备份的表，请稍后重试！");
        }
        Map<String, Object> map = JSON.parseObject(description.getDescription(), LinkedHashMap.class);
        if (CollectionUtils.isEmpty(map)) {
            return null;
        }
        List<String> backUpVersion = (List<String>) map.get("backUpVersion");
        if (CollectionUtils.isEmpty(backUpVersion)) {
            return null;
        }
        List<SysDictData> listnew = new ArrayList<>();
        for (String version : backUpVersion) {
            if (StringUtils.isBlank(version)) {
                continue;
            }
            SysDictData dicvalue = new SysDictData();
            dicvalue.setDictLabel(version);
            dicvalue.setDictValue(version);
            listnew.add(dicvalue);
        }
        if (maxVersion) {
            List<SysDictData> sysDictDataList = DictUtils.getDictCache(ReportWorldEnum.REPORT_VERSION.getCode());
            if (StringUtils.isEmpty(sysDictDataList)) {
                throw new BusinessException("没有获取到版本号，请稍后重试！");
            }
            listnew.add(0, sysDictDataList.get(0));
        }
        return listnew;
    }

    /**
     * 还原版本数据
     *
     * @param version 还原的版本号
     * @throws Exception
     */
    @Transactional
    public void reductionData(String version) {
        ResultSet rs = null;
        PreparedStatement pStemtSelect = null;
        PreparedStatement pStemtInsert = null;
        PreparedStatement pStemtDelete = null;
        try {
            if (StringUtils.isBlank(version)) {
                throw new BusinessException("没有获取到版本号，请稍后重试！");
            }
            QueryWrapper<Description> descriptionQueryWrapper = new QueryWrapper<>();
            descriptionQueryWrapper.eq("NAME", ReportWorldDescriptionEnum.BACKUPVERSION.getCode());
            Description description = descriptionService.getOne(descriptionQueryWrapper);
            if (null == description || StringUtils.isBlank(description.getDescription())) {
                throw new BusinessException("没有获取到要备份的表，请稍后重试！");
            }
            Map<String, Object> mapTableName = JSON.parseObject(description.getDescription(), LinkedHashMap.class);
            if (CollectionUtils.isEmpty(mapTableName)) {
                throw new BusinessException("没有获取到备份表配置信息，请稍后重试！");
            }
            List<String> listTableName = (List<String>) mapTableName.get("tableNameList");
            if (CollectionUtils.isEmpty(listTableName)) {
                if (CollectionUtils.isEmpty(mapTableName)) {
                    throw new BusinessException("没有获取到备份表信息，请稍后重试！");
                }
            }
            List<String> backUpVersion = (List<String>) mapTableName.get("backUpVersion");
            if (CollectionUtils.isEmpty(backUpVersion)) { //没有备份表信息
                throw new BusinessException("没有获取到备份的信息，请稍后重试！");
            }
            ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
            Connection connection = holder.getConnection();
            if (null == connection) {
                throw new BusinessException("获取数据库连接出错，请稍后重试！");
            }
            // 备份表后缀
            connection.setAutoCommit(false);
            for (String backVersion : backUpVersion) {
                String tableSuffix = StringUtils.getVersionSuffix(backVersion);
                if (!StringUtils.oneCase(version, backVersion) || StringUtils.isBlank(tableSuffix)) {
                    continue;
                }
                for (String tableName : listTableName) {
                    if (StringUtils.isBlank(tableName)) {
                        continue;
                    }
                    String sqlDelete = "delete  from  " + tableName;
                    pStemtDelete = connection.prepareStatement(sqlDelete);
                    pStemtDelete.execute();
                    // 还原对应版本的数据
                    String newTabaleName = tableName + tableSuffix;
                    String sqlInsert = "insert into   " + tableName + " select *  from  " + newTabaleName;
                    pStemtInsert = connection.prepareStatement(sqlInsert);
                    pStemtInsert.execute();
                }

            }
            // 修改还原版本之后的数据都为带审核状态
            // 获取所有版本号
            List<SysDictData> list = DictUtils.getDictCache(ReportWorldEnum.REPORT_VERSION.getCode());
            // 没有版本 或者版本号只有一个的时候不备份
            if (CollectionUtils.isEmpty(list)) {
                throw new BusinessException("没有获取到版本号，请稍后重试！");
            }
            List<String> stringList = new ArrayList<>();
            for (SysDictData dictData : list) {
                if (StringUtils.isNull(dictData) || StringUtils.isEmpty(dictData.getDictValue())) {
                    continue;
                }
                // 循环到还原的版本，跳出循环
                if (version.equals(dictData.getDictValue())) {
                    break;
                }
                stringList.add(dictData.getDictValue());
            }
            if (CollectionUtils.isEmpty(stringList)) {
                return;
            }
            UpdateWrapper<SqlScript> wrapper = new UpdateWrapper<>();
            wrapper.in("VERSION", stringList);
            SqlScript sqlScript = new SqlScript();
            sqlScript.setUpdateTime(new Date());
            sqlScript.setUpdateBy(SecurityUtils.getUsername());
            sqlScript.setStatus(YssStatusEnum.WAITING_REVIEW.getCode());
            this.update(sqlScript, wrapper);
        } catch (Exception ex) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error(ex.getMessage());
            throw new BusinessException("还原版本数据失败！" + ex.getMessage());
        } finally {
            try {
                JdbcUtil.close(pStemtDelete);
                JdbcUtil.close(pStemtInsert);
                JdbcUtil.close(pStemtSelect);
                JdbcUtil.close(rs);
            } catch (Exception ex) {
                log.error(ex.getMessage());
            }
        }
    }

    /**
     * 备份上一个版本的数据
     *
     * @throws Exception
     */
    public void backUpData() {
        ResultSet rs = null;
        PreparedStatement pStemtSelect = null;
        PreparedStatement pStemtCreate = null;
        PreparedStatement pStemtDrop = null;
        Connection connection = null;
        try {
            QueryWrapper<Description> descriptionQueryWrapper = new QueryWrapper<>();
            descriptionQueryWrapper.eq("NAME", ReportWorldDescriptionEnum.BACKUPVERSION.getCode());
            Description description = descriptionService.getOne(descriptionQueryWrapper);
            if (null == description || StringUtils.isBlank(description.getDescription())) {
                throw new BusinessException("没有获取到要备份的表，请稍后重试！");
            }
            Map<String, Object> map = JSON.parseObject(description.getDescription(), LinkedHashMap.class);
            if (CollectionUtils.isEmpty(map)) {
                return;
            }
            List<String> listTableName = (List<String>) map.get("tableNameList");
            if (CollectionUtils.isEmpty(listTableName)) {
                return;
            }
            // 上一个版本的版本号的后缀作为表名后缀
            // 获取所有版本号
            List<SysDictData> list = DictUtils.getDictCache(ReportWorldEnum.REPORT_VERSION.getCode());
            // 没有版本 或者版本号只有一个的时候不备份
            if (CollectionUtils.isEmpty(list)) {
                throw new BusinessException("没有获取到版本号，请稍后重试！");
            }
            if (list.size() < 2) { // 只有一个版本号的是否不备份
                return;
            }
            // 上一个版本的版本号
            if (null == list.get(1) || StringUtils.isBlank(list.get(1).getDictValue())) {
                return;
            }
            String lastVersion = list.get(1).getDictValue(); // 上一个版本号
            String tableSuffix = StringUtils.getVersionSuffix(lastVersion); //上一个版本号后缀
            if (StringUtils.isBlank(tableSuffix)) {
                return;
            }
            connection = dataSource.getConnection();
            if (null == connection) {
                throw new BusinessException("获取数据库连接出错，请稍后重试！");
            }
            connection.setAutoCommit(false);
            Integer numberVersion = (Integer) map.get("numberVersion");
            List<String> listUpVersion = (List<String>) map.get("backUpVersion");
            if (!CollectionUtils.isEmpty(listUpVersion)) { //还没有备份数据
                if (lastVersion.equals(listUpVersion.get(0))) { //已经备份完成了
                    return;
                }
                if (numberVersion <= listUpVersion.size() - 1) { // 设置的版本数量 大于已经备份的版本数量-1
                    for (String tableName : listTableName) {
                        // 删除最早的一个备份
                        String oldVersion = StringUtils.getVersionSuffix(listUpVersion.get(listUpVersion.size() - 1));
                        if (StringUtils.isBlank(tableName) || StringUtils.isBlank(oldVersion)) {
                            continue;
                        }
                        try {
                            String oldTabaleName = tableName + oldVersion;
                            String sqlDrop = "drop  table  " + oldTabaleName;
                            pStemtDrop = connection.prepareStatement(sqlDrop);
                            pStemtDrop.execute();
                        } catch (Exception ex) {
                            log.error(ex.getMessage());
                            continue;
                        }
                    }
                    listUpVersion.remove(listUpVersion.size() - 1);
                }
            }
            for (String version : listUpVersion) { // 备份检查，是不是已经有过备份数据了
                if (lastVersion.equals(version)) {
                    return;
                }
            }
            for (String tableName : listTableName) {
                if (StringUtils.isBlank(tableName)) {
                    continue;
                }
                String newTabaleName = tableName + tableSuffix;
                // 备份上一个版本的数据
                try {
                    // 复制表结构，包含表的索引信息
                    String sqlCreate = "CREATE  TABLE  " + newTabaleName + " LIKE  " + tableName;
                    pStemtCreate = connection.prepareStatement(sqlCreate);
                    pStemtCreate.execute();
                    // 备份数据
                    String sqlInsertData = "INSERT INTO  " + newTabaleName + " SELECT *  FROM  " + tableName;
                    pStemtCreate = connection.prepareStatement(sqlInsertData);
                    pStemtCreate.execute();
                } catch (Exception ex) {
                    log.error(ex.getMessage());
                    continue;
                }
            }
            Map<String, Object> newMap = new HashMap<>();
            if (CollectionUtils.isEmpty(listUpVersion)) {
                listUpVersion = new ArrayList<>();
                listUpVersion.add(0, lastVersion);
            } else {
                listUpVersion.add(0, lastVersion);
            }
            newMap.put("backUpVersion", listUpVersion);
            newMap.put("numberVersion", numberVersion);
            newMap.put("tableNameList", listTableName);
            String json = JSONObject.toJSONString(newMap, SerializerFeature.WriteMapNullValue);
            description.setDescription(json);
            descriptionService.updateById(description);
            connection.commit();
        } catch (Exception ex) {
            try {
                connection.rollback();
            } catch (Exception e) {
                log.error(e.getMessage());
            }
            log.error("备份数据信息失败！" + ex.getMessage());
            //throw new BusinessException("备份数据信息失败！" + ex.getMessage());
        } finally {
            try {
                JdbcUtil.close(pStemtCreate);
                JdbcUtil.close(pStemtDrop);
                JdbcUtil.close(pStemtSelect);
                JdbcUtil.close(rs);
                JdbcUtil.close(connection);
            } catch (Exception ex) {
                log.error(ex.getMessage());
            }
        }
    }

    /**
     * 判断业务主键相同的数据，是否有差异
     *
     * @param msgInfo
     * @param sqlScriptVO
     * @param listInsert
     * @param rs
     */
    private void compareData(StringBuffer msgInfo, SqlScriptVO sqlScriptVO, List<Object> listInsert, ResultSet rs) {
        try {
            if (StringUtils.isEmpty(sqlScriptVO.getListCompare())) { //设置了比较字段的
                msgInfo.append("***\r\n");
                return;
            }
            List<String> listCompareCloum = new ArrayList<>();
            for (DatabaseDispose dispose : sqlScriptVO.getListCompare()) {
                listCompareCloum.add(dispose.getProp());
            }
            List<String> listCloum = sqlScriptVO.getDataTypeCloumName(); // 字段名称
            StringJoiner buffer = new StringJoiner(",");
            for (int i = 0; i < listCloum.size(); i++) {
                if (!listCompareCloum.contains(listCloum.get(i))) {
                    continue;
                }
                String value = rs.getString(listCloum.get(i));
                Object valueInsert = listInsert.get(i);
                if (StringUtils.isEmpty(value)) {
                    value = "NULL";
                }
                if (null == valueInsert || StringUtils.isEmpty(valueInsert.toString())) {
                    valueInsert = "NULL";
                }
                if (!value.equals(valueInsert.toString())) {
                    buffer.add(listCloum.get(i));
                    buffer.add("原来的值：【" + value + "】");
                    buffer.add("新的值：【" + valueInsert + "】");
                }
            }
            if (StringUtils.isNotEmpty(buffer.toString())) {
                msgInfo.append("字段").append(buffer).append("存在差异").append("***\r\n");
            } else {
                msgInfo.append("无差异").append("***\r\n");
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
            msgInfo.append("***\r\n");
        }
    }


    /**
     * 检查表名,字段名，函数，视图，储存过程名称规范
     *
     * @param name
     */
    public void nameCheck(String name) {
        YssResponse<String> response = remoteConfigService.getConfigByKey(YssConfigEnum.REPORTWORLD_NAME_CHECK.getCode(), SecurityConstants.INNER);
        YssResponse<String> responseMsg = remoteConfigService.getConfigByKey(YssConfigEnum.REPORTWORLD_NAME_CHECKMSG.getCode(), SecurityConstants.INNER);
        if (StringUtils.isNotNull(response.getData()) && StringUtils.isNotEmpty(response.getData()) && !Pattern.matches(response.getData(), name)) {
            throw new BusinessException("<font color='red'>***名称【" + name + "】" + responseMsg.getData() + "***</font>");
        }
        YssResponse<String> responseKey = remoteConfigService.getConfigByKey(YssConfigEnum.REPORTWORLD_NAME_CHECK_KEYWORDS.getCode(), SecurityConstants.INNER);
        if (StringUtils.isNotNull(responseKey.getData()) && StringUtils.isNotEmpty(responseKey.getData())
                && StringUtils.oneCase(name, responseKey.getData())) {
            throw new BusinessException("<font color='red'>***名称【" + name + "】为系统设定的关键字，请检查！***</font>");
        }
    }

    /**
     * 检查数据版本和原来版本是否一直，修改字段名称，删除字段名称，修改表名等，跨版本不能修改
     */
    private boolean checkVersion(String version, String checkVersion) {
        if (!"true".equals(checkVersion)) {
            return true;
        }
        // 获取修改记录信息文件 取当前版本号的数据
        List<SysDictData> dictDatas = DictUtils.getDictCache(ReportWorldEnum.REPORT_VERSION.getCode());
        if (StringUtils.isEmpty(dictDatas)) {
            throw new BusinessException("没有获取到版本号，请稍后重试！");
        }
        if (StringUtils.isEmpty(version) || !version.equals(dictDatas.get(0).getDictValue())) {
            return false;
        }
        return true;
    }


    /**
     * 修改基础数据信息，直接用对应的脚本
     * 修改了标的都重新初始化配置信息
     *
     * @param baseVoList
     */
    private void updateDatabaseInfo(List<DataBaseVo> baseVoList, SqlScript sqlScript, Connection connection, StringBuffer msgInfo) {
        for (DataBaseVo vo : baseVoList) {
            try {
                if (StringUtils.isNull(vo)) {
                    continue;
                }
                if (StringUtils.isNotEmpty(vo.getSql())) { // 执行调整SQL
                    connection.prepareStatement(vo.getSql());
                }
                if (StringUtils.isNotEmpty(vo.getTableName())) { // 数据更新配置信息，重新初始化
                    DatabaseDispose databaseDispose = new DatabaseDispose();
                    databaseDispose.setTableName(vo.getTableName());
                    databaseDispose.setHisVersion(sqlScript.getHisVersion());
                    databaseDisposeService.initDispose(databaseDispose, false);
                }
                msgInfo.append("<font color='red'>***基础数据对应的表【" + vo.getTableName().replace(ReportWorldEnum.RW_DB_SUFFIX.getCode(), ""))
                        .append("】结构发生变化，请联系管理员调整版本工具对比策略文件信息！***</font>\r\n");
            } catch (Exception ex) {
                msgInfo.append("<font color='red'>***基础数据对应的表【" + vo.getTableName().replace(ReportWorldEnum.RW_DB_SUFFIX.getCode(), ""))
                        .append("】数据管理平台调整结构失败，请联系管理员更新对应表结构信息！***</font>\r\n");
                log.error(ex.getMessage());
                continue;
            }
        }
    }

}
